简体   繁体   English

React - 通过功能组件传递 props up 组件树

[英]React - passing props up components tree through functional components

I want to pass a simple string, number or boolean up more than one level in my component tree.我想在我的组件树中将一个简单的字符串、数字或 boolean 向上传递一个以上的级别。 From what I read I need to do this with callback functions but I can't seem to get the logic right.根据我读到的内容,我需要使用回调函数来执行此操作,但我似乎无法正确理解逻辑。

Here is a sample of where I pass a prop down from Parent App to grandchild Breadcrumb.这是我将道具从父应用程序传递给孙子面包屑的示例。 I would like this prop to actually come from the last child in the tree, the "ResultsPage" component.我希望这个道具实际上来自树中的最后一个孩子,即“ResultsPage”组件。

I realise there are better ways of doing sth like this (redux, context, different structure, etc), the point here for me is learning and to understand how to use callback functions and how to pass a prop up several more than 1 level.我意识到有更好的方法来做这样的事情(redux、上下文、不同的结构等),对我来说,这里的重点是学习和理解如何使用回调函数以及如何传递一个多于 1 个级别的支撑。

Newbie friendly please - thanks for any input:)新手友好请-感谢您的任何意见:)

class App extends React.Component {
  render() {
    return (
      <>
        <h1>Top level app</h1>

        {/* I import the header and pass down prop */}
        <Header currentLocation="Results Page" />

        {/* I import the main app content */}
        <ResultsPage />
      </>
    );
  }
}

function Header(props) {
  return (
    <>
      <h2>
        This is the header element. It will have some nav items and the
        breadcrumb I import
      </h2>

      {/* I import the breadcrumb accept the props from parent and pass the props down to child */}
      <Crumbs currentLocation={props.currentLocation} />
    </>
  );
}

function Crumbs(props) {
  return (
    <>
      {/* I display the props I passed down through the tree */}
      <h3>
        <small>This is the breadcrumb, you are on</small>{" "}
        {props.currentLocation}
      </h3>
    </>
  );
}

function ResultsPage() {
  return (
    <>
      <p>
        This is the actual results content. I would like this component to tell
        the header component that I have loaded so it can update the breadcrumb
        to let it know which page is currently loaded in the app.
      </p>
    </>
  );
}

export default App;

To complete this issue I lewave the following solutions:为了完成这个问题,我放弃了以下解决方案:

Codesandbox: Solution to the initial question Codesandbox:初始问题的解决方案

Codesandbox: Additional solution for the same problem using only functional components Codesandbox:仅使用功能组件来解决相同问题的附加解决方案

Hope it helps the next guy:)希望它可以帮助下一个人:)

Maintain a local state variable to store the location, and pass a callback function through the props to set it.维护一个本地的 state 变量来存储位置,并通过 props 传递一个回调 function 来设置它。

class App extends React.Component {
  constructor(props){
    super(props);
    this.state = {
      currentLocation : "InitialLocation"
    }
  }

  changeCurrentLocation = (newLocation) => {
    this.setState({currentLocation : newLocation})
  }

  render() {
    ...
    <ResultsPage callback={this.changeCurrentLocation}/>
  }
}

The changeCurrentLocation function takes the new location as argument and modifies the state. changeCurrentLocation function 将新位置作为参数并修改 state。 Everytime the state changes, the render function is called again.每次 state 更改时,都会再次调用渲染 function。 This would refresh the view with updated state information, in your case - currentLocation.这将使用更新的 state 信息(在您的情况下为 currentLocation)刷新视图。

function ResultsPage({ callback }) {
  useEffect(() => {
    callback('My Results');
  }, [callback])

  return (
    ...
  );
}

Best way is to do this as I think keep the state inside a redux store.最好的方法是这样做,因为我认为将 state 保存在 redux 商店中。 You can create a listener using subscribe() method in the redux to listen any dispatches from the child components from the parent component.您可以使用 redux 中的subscribe()方法创建一个侦听器,以侦听来自父组件的子组件的任何调度。

Also there is some easy method, You can use localstorage.还有一些简单的方法,你可以使用本地存储。 You can store value from the child component and listen it by the parent component using window.addEventListener('storage', function(e) { } callback method. I hope you can understand what I tried to say.您可以使用window.addEventListener('storage', function(e) { }回调方法从子组件存储值并由父组件侦听。希望您能理解我想说的话。

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

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