<Comp1 />
<div>
<Comp1 />
<Comp2 />
</div>
我是React的新手。我只想将数据从Comp2传递到其同级Comp1。我知道使用父组件传递道具,但是在这种情况下,我必须重写Comp1才能从其父获取状态,这会影响所有Comp1。我该如何使仅选择的Comp1能够接收数据而又不打扰其他数据?
答案 0 :(得分:3)
对此没有一个简单的解决方案,但是您有两个选择:
选项1
最直接的方法将是您所描述的-使用事件侦听器让Comp2将数据向上传递给其父级,然后让父级将数据向下传递回Comp1。这可以是传递给Comp1的可选道具,因此外部的Comp1不会收到该道具没关系。
例如:
import React from 'react';
const Comp1 = ({data='Default Value'}) => (
<p>{data}</p>
)
const Comp2 = ({onData}) => (
<button onClick={e => onData(Math.random())}>Change Value</button>
)
export default function App() {
let [data, setData] = React.useState(null);
return (
<div>
<Comp1/>
<div>
<Comp1 data={data}/>
<Comp2 onData={setData}/>
</div>
</div>
);
}
这可能是您最好的选择,从实际情况看,找到一种重构应用程序的方法可能会比较好,这样该选项才变得更可行。通常有一种方法可以更改您的应用程序结构,以使它更好地工作。
如果您真的希望兄弟姐妹之间有更直接的沟通渠道,可以给Comp1一个Comp2的ref,但我不鼓励这样做。
选项2
另一种选择是使用contexts。这使任何人都可以与使用相同上下文的任何人进行通信。此功能功能强大。有些人使用上下文和reducers来建立类似Redux的系统,以使应用程序的任何部分(或他们将上下文提供程序放入的较大组件)与任何其他部分进行通信。有关使用上下文管理应用程序状态的更多信息,请参见this article。
import React from 'react';
let context = React.createContext()
const Comp1 = () => {
let ctx = React.useContext(context) || {};
return <p>{ctx.data || 'Default Value'}</p>
}
const Comp2 = () => {
let ctx = React.useContext(context);
return <button onClick={e => ctx.setData(Math.random())}>Change Value</button>
}
export default function App() {
let [data, setData] = React.useState();
return (
<div>
<Comp1/>
<div>
<context.Provider value={{data, setData}}>
<Comp1/>
<Comp2/>
</context.Provider>
</div>
</div>
);
}
选项3
出于完整性考虑,第三个选择是使用Redux之类的东西来帮助共享状态。仅当您已经在使用Redux或确实想要/需要它并了解要使用的内容时,才使用此选项。 Redux并非适用于每个项目,每个人都不需要它。
旁注
我意识到您说您是React的新手。为简洁起见和其他Google员工,我在示例中使用了很多React hooks(诸如React.useState,React.useContext之类的函数)。这些可能需要一点时间来理解,我不希望您学习如何使用它们来解决您的问题。实际上,如果您是React的新手,我强烈建议您使用已经学习了如何使用的类语法使用选项1。随着更多的练习,并开始感受到第一种选择的局限性,那么您就可以开始尝试其他方法了。
答案 1 :(得分:2)
在反应中,数据总是从上到下移动,因此没有真正的方式可以将信息同级传递给同级而不经过更高的结构。您可以使用上下文,但是同样,其提供者必须包装两个兄弟组件,这意味着必须在父组件(App)中实现。它还用于在深层嵌套的同级组件之间传递数据,以避免将props传递到多个层次。在道具只需要传递一级的情况下,最好只将状态存储在父组件(App)中。
这是您的App的上下文外观(此时的麻烦多于其价值): https://codesandbox.io/s/objective-hellman-sdm55?file=/src/App.js
答案 2 :(得分:2)
对于这种用例,我建议在父组件中使用useState挂钩,并将值和函数传递给特定的子组件。
伪代码:
<Parent>
const [value, setValue] = useState();
<Comp1 onClick={setvalue} />
<Comp2 value={value} />
</Parent>
我认为,就您的用例而言,Redux和Context API有点过大。
答案 3 :(得分:1)
您可以研究状态和道具。 参考:https://flaviocopes.com/react-state-vs-props