Reactjs 消费者提供提供者的目的是什么?

Reactjs 消费者提供提供者的目的是什么?,reactjs,react-context,Reactjs,React Context,当我在查看react jss源代码时,在它们的主提供程序中遇到了下面一段代码,称为JssProvider renderProvider = (parentContext: Context) => { const {children} = this.props const context: Context = this.createContext(parentContext, this.prevContext) this.prevContext = context

当我在查看
react jss
源代码时,在它们的主提供程序中遇到了下面一段代码,称为
JssProvider

  renderProvider = (parentContext: Context) => {
    const {children} = this.props
    const context: Context = this.createContext(parentContext, this.prevContext)
    this.prevContext = context
    return <JssContext.Provider value={context}>{children}</JssContext.Provider>
  }

  render() {
    return <JssContext.Consumer>{this.renderProvider}</JssContext.Consumer>
  }
}
renderProvider=(parentContext:Context)=>{
const{children}=this.props
const context:context=this.createContext(parentContext,this.prevContext)
this.prevContext=上下文
返回{children}
}
render(){
返回{this.renderProvider}
}
}


这让我很困惑,起初我认为这是一种无需太多努力就能访问上一个上下文的递归方法。但我试着在这样的沙箱中复制它

const context = React.createContext();
const { Provider, Consumer } = context;

const FooProvider = ({ children }) => {
  const [state, setState] = React.useState({
    value: "foo",
    setValue: value => setState(p => ({ ...p, value }))
  });

  const renderProvider = context => {
    console.log(context);
    return <Provider value={state}>{children}</Provider>;
  };

  return <Consumer>{renderProvider}</Consumer>;
};

function App() {
  const onClick = setter => {
    setter("bar");
  };
  return (
    <FooProvider>
      <Consumer>
        {context => (
          <div>
            {context.value}
            <button onClick={() => onClick(context.setValue)}>Change</button>
          </div>
        )}
      </Consumer>
    </FooProvider>
  );
}
const context=React.createContext();
const{Provider,Consumer}=context;
const FooProvider=({children})=>{
常量[状态,设置状态]=React.useState({
值:“foo”,
setValue:value=>setState(p=>({…p,value}))
});
const renderProvider=上下文=>{
console.log(上下文);
返回{children};
};
返回{renderProvider};
};
函数App(){
const onClick=setter=>{
设定器(“酒吧”);
};
返回(
{context=>(
{context.value}
onClick(context.setValue)}>Change
)}
);
}

问题是提供给
renderProvider
上下文总是
未定义的


这种特殊模式的目的是什么?这里我遗漏了什么?

当组件树中有多个相同的提供程序时,它们将相互“阴影化”,就像同名变量如何相互“阴影化”一样。在渲染使用者时,它将只看到树上最近的提供者的值

所以他们在这里做的就是利用这一点。提供程序存在于树的顶部附近,并使值可供其子代使用。其中一个后代侦听该值,但随后立即生成该值的修改版本并提供该值。因此,任何低于第二个提供者的内容都只能看到修改后的值,而不能看到原始值

我不确定他们在代码中使用它的目的是什么,但我之前已经将它用于一些事情:

1) 用于仅覆盖某个部分的页面主题

我们的应用程序顶部有一个主题提供程序,指定用于样式设置的常量。但是,在树中间的某个地方是一个组件,它将读取那个全局主题,重写一些值,然后将修改后的主题提供给它的后代。这些子体只能访问修改后的主题

在我们的例子中,这让我们展示一个预览,如果主题在全球范围内应用,它会是什么样子

2) 用于聚合有关组件树的元数据

我们有一个用例,其中组件需要知道他们正在使用的应用程序的区域,因此我们在树的顶部的附近设置了一个提供者,它提供了一个值,基本上是
{page:'Login'}
(或其他)。下面是一个消费者/提供者对,它将接受并添加到其中,提供
{page:'Login',section:'Credentials'}
。然后,下面的一个将其再次扩展为
{page:'login',section:'Credentials',section:'email'}

最后,任何只使用上下文的组件(不提供自己的值)都可以知道它在应用程序中的位置。它只能从最近的祖先那里获得值,因此它拥有恰到好处的信息量

问题是提供给renderProvider的上下文始终未定义


您看到未定义的原因是,这是您创建的上下文的默认值(因为您没有将任何内容传递到
React.CreateContext()
),并且您只有一个嵌套级别。如果您有多个相互嵌套的消费者/提供者对,则每个消费者/提供者对都将注销其从最近的祖先处获得的内容,而最上面的消费者/提供者对将注销,但未定义。您只有最上面的一个。

没有完全理解,但我建议您看看仍然让我大吃一惊的东西,但是您甚至没有在renderProvider函数中使用
上下文
参数。只是记录它。感谢您详细的回答。但我不明白的是,在这种情况下,是相同的
上下文
对象。消费者在
提供者
上呈现,这是我习惯的反向流(提供者包装消费者)。消费者到底为什么在这里包装提供者?
消费者到底为什么在这里包装提供者?
消费者在那里是为了从树上更远的地方的提供者那里获取价值。然后提供程序将向树的其余部分提供修改后的值。如果只有一对这样的话,这是没用的。关键是要有很多这样的配对,所以当你沿着你遇到的树往下走:提供者->消费者/提供者->消费者/提供者->消费者/提供者->等等,这个答案是值得的。这是一个顶级的反应模式。当然!现在看来很明显。回答得好!再次感谢!