简体   繁体   English

将数据传递给相同的组件之一

[英]Pass data to one of the same components

<Comp1 />
<div>
    <Comp1 />
    <Comp2 />
</div>

I am new to React.我是 React 的新手。 I want to pass data from Comp2 to its sibling Comp1 only.我只想将数据从 Comp2 传递给它的兄弟 Comp1。 I know using a parent component to pass props but in this case I have to rewrite Comp1 to get state from its parent, which will affect all the Comp1.我知道使用父组件来传递道具,但在这种情况下,我必须重写 Comp1 以从其父组件获取 state,这将影响所有 Comp1。 How can I make only chosen Comp1 receive the data and don't bother the else?我怎样才能让只选择的 Comp1 接收数据而不打扰其他人?

There is not a straightforward solution to this, but you do have a couple of options:对此没有直接的解决方案,但您确实有几个选择:

Option 1选项1

The most direct way would be as you described - having Comp2 pass data up to its parent using an event listener, then having the parent pass it back down to Comp1.最直接的方法是您所描述的 - 让 Comp2 使用事件侦听器将数据传递给其父级,然后让父级将其传递回 Comp1。 This can be an optional prop being passed to Comp1, so it doesn't matter that your outer Comp1 won't receive that prop.这可以是传递给 Comp1 的可选道具,因此您的外部 Comp1 不会收到该道具并不重要。

For example:例如:

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>
  );
}

This is probably your best option, and by the sound of things, it might be good to find a way to refactor your app so that this option becomes more viable.这可能是您最好的选择,并且从事物的声音来看,找到一种方法来重构您的应用程序以使该选项变得更加可行可能会很好。 There's usually a way to change your app structure to make this work better.通常有一种方法可以更改您的应用程序结构以使其更好地工作。

If you really want siblings to have a more direct line of communication with each other, you could give Comp1 a ref of Comp2, but I wouldn't encourage this.如果你真的希望兄弟姐妹之间有更直接的沟通渠道,你可以给 Comp1 一个 Comp2 的ref ,但我不鼓励这样做。

Option 2选项 2

Another option would be to use contexts .另一种选择是使用contexts This gives anyone the power to communicate with anyone who uses the same context.这使任何人都可以与使用相同上下文的任何人进行交流。 There is a lot of power in this feature.此功能有很多功能。 Some people set up a Redux-like system using contexts and reducers to let any part of the application (or larger component they put the context provider in) communicate with any other part.有些人使用上下文和reducer建立了一个类似 Redux 的系统,让应用程序的任何部分(或他们放置上下文提供程序的更大组件)与任何其他部分进行通信。 See this article for more information on using contexts to manage application state.有关使用上下文管理应用程序 state 的更多信息,请参阅本文

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>
  );
}

Option 3选项 3

For completeness, A third option would be using something like Redux to help share state.为了完整起见,第三种选择是使用 Redux 之类的东西来帮助共享 state。 Only use this option if you are already using Redux, or if you really want/need it and understand what you're getting into.如果您已经在使用 Redux,或者如果您真的想要/需要它并了解您要进入的内容,请仅使用此选项。 Redux is not for every project, everyone does not need it. Redux 并不是每个项目都适用,不是每个人都需要。

Side Note边注

I realize you said you were new to React.我意识到你说你是 React 的新手。 For brevity and for other Googlers, I used a lot of React hooks in my examples (The functions like React.useState, React.useContext, etc).为了简洁起见,对于其他 Google 员工,我在示例中使用了很多React 钩子(React.useState、React.useContext 等函数)。 These can take a little bit to understand, and I don't expect you to learn how to use them just to solve your problem.这些可能需要一点时间来理解,我不希望您学习如何使用它们来解决您的问题。 In fact, if you're new to React, I would strongly encourage you to just go with option 1 using the class syntax you've learned how to use already.事实上,如果你是 React 新手,我强烈建议你使用 go 和选项 1,使用你已经学会如何使用的 class 语法。 As you get some more practice and start feeling the limits of the first option, then you can start trying the other things out.当您进行更多练习并开始感觉到第一个选项的局限性时,您就可以开始尝试其他方法了。

In react, data always moves from top to down, so there is no true way to pass information sibling to sibling without going through some higher structure.在 react 中,数据总是从上到下移动,因此没有真正的方法将信息传递给兄弟而不经过一些更高的结构。 You could use context, but again, its provider has to wrap around both sibling components, meaning it has to be implemented in the parent component(App).您可以使用上下文,但同样,它的提供者必须围绕两个兄弟组件,这意味着它必须在父组件(应用程序)中实现。 It is also intended for passing data between deeply nested sibling components to avoid passing props multiple levels deep.它还用于在深度嵌套的兄弟组件之间传递数据,以避免将 props 传递到多个层次。 In your case where props only have to be passed one level deep, it is best to just store state in the parent component(App).在您只需将道具传递一层深度的情况下,最好将 state 存储在父组件(应用程序)中。

Here is what context would look like for your App (its more trouble than its worth at this point): https://codesandbox.io/s/objective-hellman-sdm55?file=/src/App.js以下是您的应用程序的上下文(在这一点上它比它的价值更麻烦): https://codesandbox.io/s/objective-hellman-sdm55?file=/src/App.js

For this use case I would suggest using the useState hook in the parent component and passing down a value & function to the specific child components.对于这个用例,我建议在父组件中使用 useState 挂钩并将值 & function 传递给特定的子组件。

pseudo code:伪代码:

<Parent>
    const [value, setValue] = useState();
    <Comp1 onClick={setvalue} />
    <Comp2 value={value} />
</Parent>

In my opinion, for your use case, Redux and the Context API are a bit overkill.在我看来,对于您的用例,Redux 和上下文 API 有点矫枉过正。

You can research about state and props.您可以研究 state 和道具。 References: https://flaviocopes.com/react-state-vs-props参考文献: https://flaviocopes.com/react-state-vs-props

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM