React - 通过功能组件传递支撑组件树

React - passing props up components tree through functional components

我想在我的组件树中向上传递一个简单的字符串、数字或布尔值不止一个级别。根据我的阅读,我需要使用回调函数来执行此操作,但我似乎无法理解正确的逻辑。

这是我将道具从 Parent App 传递到 grandchild Breadcrumb 的示例。我希望这个道具实际上来自树中的最后一个 child,即 "ResultsPage" 组件。

我意识到有更好的方法来做这件事(redux、context、不同的结构等),对我来说这里的重点是学习和理解如何使用回调函数以及如何传递一个 prop up several超过 1 级。

请新手友好 - 感谢您的任何输入:)

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;

为了完成这个问题,我提出了以下解决方案:

Codesandbox: Solution to the initial question

Codesandbox: Additional solution for the same problem using only functional components

希望对下一个人有帮助:)

维护一个本地状态变量来存储位置,通过props传递一个回调函数来设置。

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

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

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

changeCurrentLocation 函数将新位置作为参数并修改状态。每次状态改变时,都会再次调用渲染函数。这将使用更新的状态信息刷新视图,在您的情况下 - currentLocation。

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

  return (
    ...
  );
}

最好的方法是这样做,因为我认为将状态保存在 redux 存储中。您可以在 redux 中使用 subscribe() 方法创建一个侦听器,以侦听来自父组件的子组件的任何调度。

还有一些简单的方法,你可以使用localstorage。您可以存储子组件的值,并使用 window.addEventListener('storage', function(e) { } 回调方法由父组件监听它。我希望你能理解我想说的。