Reactjs React(包装器)中的模式

Reactjs React(包装器)中的模式,reactjs,design-patterns,react-hoc,Reactjs,Design Patterns,React Hoc,你好。我正在构建一个组件树,并希望在树的其他组件中使用根组件的函数。我通过所有树抛出函数引用。 如果我需要从非根组件中的函数获取值,我也会使用该对象。 你能帮助我吗? 你能告诉我怎么做吗? 如果不难的话,请在我的代码中显示示例 import React from 'react'; class Page extends React.Component{ Answer = { value : '' } doSomething(){ co

你好。我正在构建一个组件树,并希望在树的其他组件中使用根组件的函数。我通过所有树抛出函数引用。 如果我需要从非根组件中的函数获取值,我也会使用该对象。 你能帮助我吗? 你能告诉我怎么做吗? 如果不难的话,请在我的代码中显示示例

import React from 'react';

class Page extends React.Component{

    Answer = {
        value : ''
    }

    doSomething(){

        console.log(this.Answer.value);
        console.log('Ready!');
    }
    
    render(){
        return(
            <div>
                <div>
                    <Body 
                        ParentFunc={()=>this.doSomething()} 
                        ParentParameters={this.Answer}
                    />
                </div>
            </div>
        )
    }
}

export default Page

class Body extends React.Component{
    render(){

        const{
            ParentFunc,
            ParentParameters
        } = this.props
        
        return(
            <div>
                <div>
                    <SomeComponent 
                        ParentFunc={()=>ParentFunc()}
                        ParentParameters={ParentParameters}
                    />
                </div>
            </div>
        )
    }
}

class SomeComponent extends React.Component{

    getAnswer(){
        
        const{
            ParentFunc,
            ParentParameters
        } = this.props

        ParentParameters.value = 'Some text'
        
        ParentFunc()
    }
    
    render(){
        
        return(
            <div onClick={()=>this.getAnswer()}>
                We can?
            </div>
        )
    }
}


从“React”导入React;
类页扩展了React.Component{
答案={
值:“”
}
doSomething(){
console.log(this.Answer.value);
console.log('Ready!');
}
render(){
返回(
this.doSomething()}
ParentParameters={this.Answer}
/>
)
}
}
导出默认页面
类主体扩展了React.Component{
render(){
常数{
ParentFunc,
父参数
}=这是道具
返回(
ParentFunc()}
ParentParameters={ParentParameters}
/>
)
}
}
类SomeComponent扩展了React.Component{
getAnswer(){
常数{
ParentFunc,
父参数
}=这是道具
ParentParameters.value='Some text'
ParentFunc()
}
render(){
返回(
this.getAnswer()}>
我们可以?
)
}
}

我认为单靠高阶组件无法解决支柱钻井的基本问题。A更适合于提供值和函数,以便“希望在树的其他组件中使用根组件的函数”

上下文提供了一种通过组件树传递数据的方法,而无需在每个级别手动传递道具。 在典型的React应用程序中,数据是自上而下传递的(父级到子级) (儿童)通过道具,但这种使用对于某些类型来说可能很麻烦 许多人需要的道具(如区域设置首选项、UI主题) 应用程序中的组件。上下文提供了一种共享的方式 组件之间的值,而不必显式传递 一个道具穿过树的每一层

首先创建上下文和提供程序组件:

const QnAContext = React.createContext({
  answer: {
    value: ""
  },
  doSomething: () => {}
});

const QnAProvider = ({ children }) => {
  const answer = {
    value: ""
  };

  const doSomething = () => {
    console.log(answer.value);
    console.log("Ready!");
  };

  return (
    <QnAContext.Provider value={{ answer, doSomething }}>
      {children}
    </QnAContext.Provider>
  );
};
使用上下文:

  • 基于类的组件通过模式使用上下文

    然后,您可以装饰要将上下文值注入其中的组件

    const DecoratedSomeComponent = withQnAContext(SomeComponent);
    
    ...
    
    <DecoratedSomeComponent>We can with HOC?</DecoratedSomeComponent>
    

    我不相信单靠高阶组件就能解决支柱钻井的基本问题。A更适合于提供值和函数,以便“希望在树的其他组件中使用根组件的函数”

    上下文提供了一种通过组件树传递数据的方法,而无需在每个级别手动传递道具。 在典型的React应用程序中,数据是自上而下传递的(父级到子级) (儿童)通过道具,但这种使用对于某些类型来说可能很麻烦 许多人需要的道具(如区域设置首选项、UI主题) 应用程序中的组件。上下文提供了一种共享的方式 组件之间的值,而不必显式传递 一个道具穿过树的每一层

    首先创建上下文和提供程序组件:

    const QnAContext = React.createContext({
      answer: {
        value: ""
      },
      doSomething: () => {}
    });
    
    const QnAProvider = ({ children }) => {
      const answer = {
        value: ""
      };
    
      const doSomething = () => {
        console.log(answer.value);
        console.log("Ready!");
      };
    
      return (
        <QnAContext.Provider value={{ answer, doSomething }}>
          {children}
        </QnAContext.Provider>
      );
    };
    
    使用上下文:

    • 基于类的组件通过模式使用上下文

      然后,您可以装饰要将上下文值注入其中的组件

      const DecoratedSomeComponent = withQnAContext(SomeComponent);
      
      ...
      
      <DecoratedSomeComponent>We can with HOC?</DecoratedSomeComponent>
      

      根据您当前的代码,我假设
      Body
      在传递给
      SomeComponent
      之前不会修改
      ParentFunc
      ParentParameters
      的值

      你有等级制度

      <Page>
        <Body>
          <SomeComponent>
        </Body>
      </Page>
      
      我们通过在
      中使用
      元素来设置
      子项
      道具:


      根据您当前的代码,我假设
      Body
      在传递给
      SomeComponent
      之前不会修改
      ParentFunc
      ParentParameters
      的值

      你有等级制度

      <Page>
        <Body>
          <SomeComponent>
        </Body>
      </Page>
      
      我们通过在
      中使用
      元素来设置
      子项
      道具:


      你到底想用什么来制作更高阶的组件?“想在树的其他组件中使用根组件的函数”听起来更像是要创建上下文提供程序,并通过上下文提供要调用的函数。注意!不要使用上下文来避免将属性向下传递到多个级别。在不同级别的许多组件中必须提供相同的数据的情况下,才会出现真正的需求。我想使用pattern,那么你想创作什么,而你还没有创作?你的问题不清楚。我明白了,如果你指的是第节,这只是说你可以把
      this.getAnswer()}>括起来……你到底想用什么做一个更高阶的组件?“想在树的其他组件中使用根组件的函数”听起来更像是要创建上下文提供程序,并通过上下文提供要调用的函数。注意!不要使用上下文来避免将属性向下传递到多个级别。在不同级别的许多组件中必须提供相同的数据的情况下,才会出现真正的需求。我想使用pattern,那么你想创作什么,而你还没有创作?您的问题不清楚。我明白了,如果您指的是第节,这只是说您可以将
      this.getAnswer()}>括起来。。。
      
      const QnAContext = React.createContext({
        answer: {
          value: ""
        },
        doSomething: () => {}
      });
      
      const QnAProvider = ({ children }) => {
        const answer = {
          value: ""
        };
      
        const doSomething = () => {
          console.log(answer.value);
          console.log("Ready!");
        };
      
        return (
          <QnAContext.Provider value={{ answer, doSomething }}>
            {children}
          </QnAContext.Provider>
        );
      };
      
      const withQnAContext = (Component) => (props) => (
        <QnAContext.Consumer>
          {(value) => <Component {...props} {...value} />}
        </QnAContext.Consumer>
      );
      
      class SomeComponent extends React.Component {
        getAnswer = () => {
          const { doSomething, answer } = this.props;
      
          answer.value = "Some text";
      
          doSomething();
        };
      
        render() {
          return (
            <button type="button" onClick={this.getAnswer}>
              {this.props.children}
            </button>
          );
        }
      }
      
      const DecoratedSomeComponent = withQnAContext(SomeComponent);
      
      class Body extends React.Component {
        render() {
          return (
            <div>
              <div>
                <QnAContext.Consumer>
                  {({ answer, doSomething }) => (
                    <SomeComponent doSomething={doSomething} answer={answer}>
                      We can?
                    </SomeComponent>
                  )}
                </QnAContext.Consumer>
              </div>
              <div>
                <DecoratedSomeComponent>We can with HOC?</DecoratedSomeComponent>
              </div>
            </div>
          );
        }
      }
      
      class Page extends React.Component {
        render() {
          return (
            <div>
              <div>
                <Body />
              </div>
            </div>
          );
        }
      }
      
      export default function App() {
        return (
          <div className="App">
            <h1>Hello CodeSandbox</h1>
            <h2>Start editing to see some magic happen!</h2>
      
            <QnAProvider>
              <Page />
            </QnAProvider>
          </div>
        );
      }
      
      <Page>
        <Body>
          <SomeComponent>
        </Body>
      </Page>
      
      class Body extends React.Component{
          render() {
              return(
                  <div>
                      <div>
                          {this.props.children}
                      </div>
                  </div>
              )
          }
      }
      
      render() {
        return (
          <div>
            <div>
              <Body>
                <SomeComponent
                  ParentFunc={() => this.doSomething()}
                  ParentParameters={this.Answer}
                />
              </Body>
            </div>
          </div>
        );
      }
      
      import React from "react";
      
      class Body extends React.Component {
        render() {
          return (
            <div>
              <div>{this.props.children}</div>
            </div>
          );
        }
      }
      
      class SomeComponent extends React.Component {
        state = {
          showAnswer: false
        };
      
        onClick() {
          // update answer in parent
          this.props.setAnswer("Some text");
          // change state to reveal answer
          this.setState({ showAnswer: true });
        }
      
        render() {
          return (
            <div>
              {this.state.showAnswer && <div>Answer is: {this.props.answer}</div>}
              <div onClick={() => this.onClick()}>We can?</div>
            </div>
          );
        }
      }
      
      class Page extends React.Component {
        state = {
          value: ""
        };
      
        render() {
          return (
            <div>
              <div>
                <Body>
                  <SomeComponent
                    answer={this.state.value}
                    setAnswer={(answer) => this.setState({ value: answer })}
                  />
                </Body>
              </div>
            </div>
          );
        }
      }
      
      export default Page;