【问题标题】:How to access particular child state from parent with multiple children?如何从有多个孩子的父母那里访问特定的孩子状态?
【发布时间】:2021-08-22 23:43:24
【问题描述】:

假设我在 React 中有一个父组件,它具有同一个组件类的 3 个单独的子组件(意思是,在 Parent 类中我有 3 个子组件)。如何在 Parent 组件中访问每个孩子的状态?

我最初的想法是为我想要访问的每个孩子的状态设置一个单独的变量(我只想访问每个孩子的填充变量)。但我觉得这对于 React 已经存在的东西来说肯定是一个草率的解决方案,所以不胜感激。

下面的示例代码用于说明目的。

const Parent = (props) => {

return (
<div>
    <Child/>
    <Child/>
    <Child/>
</div>
);
}


const Child = (props) => {
const [filled, setFilled] = useState(false);

return (
    <div></div>
);
}

也许更好的问题是我如何访问特定的孩子?一旦访问,我如何访问它的填充状态(回调函数)?我已经阅读了有关 useRef 的内容,我应该在这里查看吗?

【问题讨论】:

  • 您能否更具体地描述您要解决的特定于应用程序的问题?一般来说,如果您遵循"Lifting State Up" 中的指南,您所描述的模式可以完全避免。

标签: javascript reactjs


【解决方案1】:

如果你想要做的是向父母报告孩子的状态,你可以通过从父母那里通过 props 传递一个函数来报告该状态,如下所示:

const Parent = (props) => {

    const reportChildState = (value) =>{
        //do something with the child filled state
    }

    return (
    <div>
        <Child reportState={reportChildState}/>
        <Child reportState={reportChildState}/>
        <Child reportState={reportChildState}/>
    </div>
    );
}


const Child = (props) => {

    //in here you can call props.reportChildState(filled)
    const [filled, setFilled] = useState(false);

    return (
        <div></div>
    );
}

【讨论】:

    【解决方案2】:

    据我所知,没有办法从父组件访问子组件状态。唯一的解决方案是将 state 对象作为 prop 传递给 child,使用 context API 或使用 thirst 方状态管理,例如 redux。

    我不会使用 useref 来访问孩子的状态。

    【讨论】:

      【解决方案3】:

      您实际上不会直接访问孩子来检索他们的状态。你在这里想要的是一个包含父组件的上下文。查看React Context API。简而言之,您可以创建一个“上下文”,其中包含需要在多个组件之间共享的状态。创建上下文后,还会使用该上下文创建 Provider。此提供程序是一个接受 value 属性的组件。此道具包含上下文中所有状态值和设置器函数的对象。 Provider 组件的子组件可以使用useContext 挂钩从Providervalue 属性中检索值和函数。

      代码示例:

      MyContext.js

      import React, {createContext, useState} from 'react';
      
      // Create the context and give it default values
      export const MyContext = createContext(defaultValuesObject);
      
      // We create a component that wraps around the provider, and is stateful. The states and their setters are placed into the provider, which is then returned.
      const MyProvider = (props) => {
          const [firstName, setFirstName] = useState("")
          const [lastName, setLastName] = useState("")
          
          const dataToShare = {
              firstName, 
              setFirstName, 
              lastName, 
              setLastName,
          }
      
          // Return the context provider with the data already inside, and fill the children.
          return (
              <MyContext.Provider value={dataToShare}>
                  {props.children}
              </MyContext.Provider>
          )
      
      }
      

      我们现在有了提供者。在父组件的代码中,使用 useContext 挂钩让组件可以访问存储在提供程序组件中的值和函数。

      MyParentComponent.jsx

      import React, {useContext} from 'react';
      import MyProvider, { MyContext } from 'MyContext'
      
      const MyComponent = (props) => {
          // useContext returns the value stored in the provider so we can use it and the functions inside. The context is maintained inside the states in the provider.
          const providerValue = useContext(MyContext)
          // OR
          const { firstName, setFirstName, lastName, setLastName } = useContext(MyContext)
          return ( 
              <div>
                  // Provide the first child component with the values and functions from the context
                  <MyChildComponentOne someProp={providerValue} />
                  // Provide the second child component with the values and functions from the context
                  <MyChildComponentTwo someProp={providerValue} />
                  // Provide the second third component with the values and functions from the context
                  <MyChildComponentThree someProp={providerValue} />
              <div/>
          )
      }
      

      现在,我们仍然无法在没有提供程序的情况下使用上下文,提供程序必须围绕为该特定上下文调用 useContext 的组件。假设在 App.jsx 内部使用 ParentComponent:

      App.jsx

      ...imports and whatever other code you have in here
      
         /// The jsx for the App component or whatever component calls MyParentComponent
         return <div>
                    <MyProvider>
                        <MyParentComponent>
                    </MyProvider>
                </div>
      
      

      要重新迭代,您将子/父组件的状态取出,并将它们放入由上下文创建的提供程序中。 Provider 的子组件可以调用useContext 并访问Provider 的value 属性中的数据和函数。

      【讨论】:

        【解决方案4】:

        没有直接的方式将信息从孩子传递给父母,只能反过来。

        但这意味着您也可以将函数从父级传递给子级!实现所需的一种常见模式是将状态集函数传递给孩子,这样它就可以改变父母的状态。像这样:

        const Parent = (props) => {
          const [childStates, setChildStates] = useState({ child1: '', child2: '',  child3: '' })
        
          return (
          <div>
              <Child 
                state={childStates.child1} 
                setState={(val) => setChildStates((prev) => ({ ...prev, child1: val }))}
              />
              <Child 
                state={childStates.child2} 
                setState={(val) => setChildStates((prev) => ({ ...prev, child2: val }))}
              />
              <Child 
                state={childStates.child3} 
                setState={(val) => setChildStates((prev) => ({...prev, child3: val }))}
              />
          </div>
          );
        }
        

        【讨论】:

          猜你喜欢
          • 2018-03-19
          • 1970-01-01
          • 1970-01-01
          • 2017-05-31
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-06-14
          • 1970-01-01
          相关资源
          最近更新 更多