生成上下文的DRY原则

huangapple go评论72阅读模式
英文:

DRY for generating contexts

问题

考虑以下代码:

const CourseContext = createContext()
const CourseProvider = ({children}) => {
    const [course, setCourse] = useState(null);
    return (
        <CourseContext.Provider value={{course, setCourse}}>
            {children}
        </CourseContext.Provider>
    )
}

还可以有另一个具有非常相似结构的上下文:

const SaleContext = createContext()
const SaleProvider = ({children}) => {
    const [sale, setSale] = useState({name: "A great course", price: 25});
    return (
        <SaleContext.Provider value={{sale, setSale}}>
            {children}
        </SaleContext.Provider>
    )
}

而不是为每个上下文制作另一个此代码结构的副本,我希望能够根据状态变量名称(例如 "course""sale")和初始值(例如 null{name: "A great course", price: 25})轻松生成上下文。

我知道可以使用 eval 来实现这一点。是否有更简单/更符合习惯的方式我可能遗漏了?

英文:

Consider:

const CourseContext = createContext()
const CourseProvider = ({children}) => {
    const [course, setCourse] = useState(null);
    return (
        <CourseContext.Provider value={{course, setCourse}}>
            {children}
        </CourseContext.Provider>
    )
}

There can be another context having a very similar structure:

const SaleContext = createContext()
const SaleProvider = ({children}) => {
    const [sale, setSale] = useState({name: "A great course", price: 25});
    return (
        <SaleContext.Provider value={{sale, setSale}}>
            {children}
        </SaleContext.Provider>
    )
}

Rather than making another copy of this code structure for every context, I want to be able to easily produce contexts based on the state variable name, such as "course" or "sale", and the initial value, such as null or {name: "A great course", price: 25}.

I know that I could do this using eval. Is there a simpler / more idiomatic way I am missing?

答案1

得分: 2

是的,你可以创建一个函数,该函数返回针对提供的名称和默认值的两个作用域函数。

例如...

function makeContext(name, defaultValue) {
   const setName = `set${name[0].toUpperCase()}${name.substring(1)}`;
   const Context = createContext();
   const Provider = ({ children }) => {
      const [value, setValue] = useState(defaultValue);
      return (
         <Context.Provider value={{ [name]: value, [setName]: setValue }}>
            {children}
         </Context.Provider>
      )
   }
   return [
      Context,
      Provider
   ]
}

const [CourseContext, CourseProvider] = makeContext('course', null);
const [SaleContext, SaleProvider] = makeContext('sale', { name: "A great course", price: 25 });

希望这对你有帮助!

英文:

Yes, you can create a function that returns the 2 functions scoped to a name and default you provide.

eg..

function makeContext(name, defaultValue) {
   const setName = `set${name[0].toUpperCase()}${name.substring(1)}`;
   const Context = createContext();
   const Provider = ({ children }) =&gt; {
      const [value, setValue] = useState(defaultValue);
      return (
         &lt;Context.Provider value={{ [name]: value, [setName]: setValue }}&gt;
            {children}
         &lt;/Context.Provider&gt;
      )
   }
   return [
      Context,
      Provider
   ]
}

const [CourseContext, CourseProvider] = makeContext(&#39;course&#39;, null);
const [SaleContext, SaleProvider] = makeContext(&#39;sale&#39;, { name: &quot;A great course&quot;, price: 25 });

huangapple
  • 本文由 发表于 2023年6月9日 06:04:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/76435993.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定