【问题标题】:How to fire a function in child from parent in react?如何在反应中从父母那里触发孩子的功能?
【发布时间】:2019-10-01 20:54:46
【问题描述】:

我的 React 应用程序包含三个组件。其中两个是子组件,另一个是父组件。我需要通过父组件将数据(projectId)从一个子组件传递给另一个子组件,并在接收到数据后触发一个函数。作为我的示例,我将 projectId 从 ChildOne 发送到 Parent,然后将 projectId 从 Parent 发送到 ChildTwo。 ChildTwo 有一个名为 setProject(projectId) 的函数,我需要在收到 projectID 后触发它。 问题是我无法通过单击 ChildOne 中的按钮在 ChildTwo 中触发 getProjectId 函数。我还尝试了对我不起作用的 componentDidMount 和 componentWillReceiveProps。 我该怎么做?

这是我尝试过的

ChildOne:

class ChildOne extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
          projectId: 3,
        };
    }

    sendProjectId = (projectId) => {
       this.props.sendId(projectId)
    }

    render() {
       return(
         <button onClick={() => this.sendProjectId(this.state.projectId)}>
            Click
         </button>
       )
    }
}

家长:

class Parent extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
          projectId: '',
        };
    }

    getId = (proId) => {
       this.setState({
          projectId : proId
       })
    }

    render() {
       return(
         <div>
           <CildOne sendId={this.getId} />

           <CildTwo sendOneId={this.state.projectId} />
         </div>
       )
    }
}

孩子二:

class ChildTwo extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
          projectId: '',
        };
    }

    getProjectId = (this.props.sendOneId) => {
       //Do something with this.props.sendOneId
    }

    render() {
       return(
         <div></div>
       )
    }
}

【问题讨论】:

  • 你打算用 ChildTwo 中的this.props.sendOneId 做什么?解决方案将取决于您的用例
  • 我认为 componentWillReceiveProps 在您的场景中应该可以正常工作。
  • componentWillReceiveProps 已弃用。

标签: javascript reactjs


【解决方案1】:

如果你想设置一些状态,你可以尝试一个功能组件或钩子

function ChildOne(props) {
  const [projectId, setProjectId] = useState(3);
  function sendProjectId(data){
       props.sendId(projectId)
    }
   return(
         <button onClick={() => sendProjectId(projectId)}>
            Click
         </button>
       )
}



function ChildTwo(props) {
  const [state, setState] = useState('')
  function getProjectId(data) {
       //Do something with this.props.sendOneId
       console.log(`data here ${data}`)
       return false;
    }
    getProjectId(props.sendOneId)
  return (
    <div>
    </div>
  )
}


function Parent(){
   const [projectId, setProjectId] = useState('');
   function getId(proId) {
     setProjectId(proId)
   }
   return(
         <div>
           <ChildOne sendId={getId} />

           <ChildTwo sendOneId={projectId} />
         </div>
       )
}



【讨论】:

    【解决方案2】:

    您可能应该使用componentDidUpdate 和条件来检查state 中的projectId 是否需要在sendOneId 更改时更新。然后可以使用setStates 回调调用getProjectId

    componentDidUpdate() {
      const { projectId: currentProjectId } = this.state;
      const { sendOneId: projectId } = this.props;
      if (projectId !== currentProjectId) {
        this.setState({ projectId }, () => this.getProjectId());
      }
    }
    

    完整的工作示例:

    class ChildOne extends React.Component {
        
      constructor(props) {
        super(props);
          this.state = {
            projectId: 3,
          };
        }
    
        sendProjectId = (projectId) => {
          this.props.sendId(projectId)
        }
    
        render() {
          return (
            <button onClick={() => this.sendProjectId(this.state.projectId)}>
              Click
            </button>
          );
        }
    }
    
    class Parent extends React.Component {
      
      constructor(props) {
        super(props);
        this.state = {
          projectId: '',
        };
      }
    
      getId = (projectId) => {
        this.setState({ projectId });
      }
    
      render() {
        return (
          <div>
            <ChildOne sendId={this.getId} />
            <ChildTwo sendOneId={this.state.projectId} />
          </div>
        )
      }
    
    }
    
    class ChildTwo extends React.Component {
    
        constructor(props) {
          super(props);
          this.state = {
            projectId: '',
          };
        }
    
        componentDidUpdate() {
          const { projectId: currentProjectId } = this.state;
          const { sendOneId: projectId } = this.props;
          if (projectId !== currentProjectId) {
            this.setState({ projectId }, () => this.getProjectId());
          }
        }
    
        getProjectId = () => {
          console.log(this.state.projectId);
        }
    
        render() {
          return (
            <div></div>
          );
        }
    }
    
    ReactDOM.render(
      <Parent />,
      document.getElementById('container')
    );
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
    <div id="container"></div>

    【讨论】:

      【解决方案3】:

      你在ChildTwo组件的getProjectId函数中做错了。

      您的函数无法从 prop 接收任何参数。

      所以,你的函数应该是这样的:

      getProjectId = (sendOneId) => {
         //Do something with this.props.sendOneId
      }
      

      那么你应该像这样使用componentWillReceiveProps

      componentWillReceiveProps(nextProps) {
        if (this.props.sendOneId !== nextProps.sendOneId) {
          this.getProjectId(nextProps.sendOneId);
        }
      }
      

      这是我为解决您的问题而创建的一个工作代码框示例: https://codesandbox.io/s/5v4rn7qnll

      【讨论】:

      • componentWillReceiveProps 已弃用,will cease working in v17.
      • @Andy 我知道componentWillReceiveProps 已被弃用。但是OP提到他尝试了componentWillReceiveProps并没有成功。这意味着他现在可以安全地使用它。
      【解决方案4】:

      这将取决于ChildTwo 想要用所述数据完成什么。

      案例 1:

      ChildTwo 打算用对应的projectId 获取一些数据并显示在组件中。然后,您可以轻松地在父组件中获取此数据并将数据作为props 向下传递。

      class Parent extends React.Component {
          constructor(props) {
              super(props);
              this.state = {
                projectId: '',
                dataForChildTwo: null,
              };
          }
      
          getId = (proId) => {
             this.setState({
                projectId : proId,
                dataForChildTwo: fetchData(proId)
             })
          }
      
          render() {
             return(
               <div>
                 <CildOne sendId={this.getId} />
      
                 <CildTwo data={this.state.dataForChildTwo} />
               </div>
             )
          }
      }
      

      案例 2:

      ChildTwo 打算在projectId 更改时对其内部的内容进行一些更改。然后你可以使用componentDidUpdate hook 来查看 prop 是否改变并做出响应。

      class ChildTwo extends React.Component {
          constructor(props) {
              super(props);
              this.state = {
                projectId: '',
              };
          }
      
          getProjectId = (this.props.sendOneId) => {
             //Do something with this.props.sendOneId
          }
      
          componentDidUpdate(prevProps) {
            if(this.props.projectId!==prevProps.projectId) {
              // do something
            }
          }
      
          render() {
             return(
               <div></div>
             )
          }
      }
      

      案例 3

      如果上述情况都不适合您,那么您可以在 projectId 更改时使用 key 属性手动重新加载整个组件:

      <CildTwo key={this.state.projectId} sendOneId={this.state.projectId} />
      

      注意:这会不必要地重新加载整个组件。

      【讨论】:

      • 谢谢!您的案例 3 回答解决了我的问题!
      猜你喜欢
      • 2022-08-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-31
      • 2018-09-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多