【问题标题】:React - passing props up components tree through functional componentsReact - 通过功能组件传递 props up 组件树
【发布时间】:2020-09-19 17:16:32
【问题描述】:

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

这是我将道具从父应用程序传递给孙子面包屑的示例。我希望这个道具实际上来自树中的最后一个孩子,即“ResultsPage”组件。

我意识到有更好的方法来做这样的事情(redux、上下文、不同的结构等),对我来说,这里的重点是学习和理解如何使用回调函数以及如何传递一个多于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

希望它可以帮助下一个人:)

【问题讨论】:

  • 您尝试了哪些方法,为什么没有成功?
  • 我花了整整 2 天时间阅读教程和文档。我的问题是它们总是非常复杂,或者它们使用类组件并且我无法将其转换为函数组件,或者当我真的只想发送一个道具时它们使用状态等等。当我试图理解上面的内容时也是如此:如何将道具向下传递几层。我找不到任何简单的例子。所以我花了几天的时间来整理教程和文档,直到我能够构建你在上面看到的这个非常简单的组件树。以上帮助我理解了!

标签: javascript reactjs react-props


【解决方案1】:

维护一个局部状态变量来存储位置,并通过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 (
    ...
  );
}

【讨论】:

  • 谢谢 Edison,我试过了,但它会报错:codesandbox.io/s/pass-props-up-wb03r?file=/src/App.js
  • 这里的初始答案存在一些问题,我已对其进行了修正:changeCurrentLocation 必须使用箭头函数才能在范围内保持正确的this,并且不应调用回调渲染函数,因为这将导致无限循环(在渲染时,调用回调设置状态,触发另一个渲染导致再次调用回调等)codesandbox.io/s/pass-props-up-o6scl?file=/src/App.js
  • 非常感谢乔希!这行得通,我实际上也设法弄清楚了如何使用新状态:) 我已经更新了沙箱,我会评论所有行以供我自己理解,直到我弄清楚你在那里做了什么。
  • 谢谢@Josh,我也是在 StackOverflow 中回答问题的新手。克里斯,如果有效,请接受答案。谢谢:)
  • 爱迪生和乔希,感谢您的宝贵时间。我接受了答案,但@edison,你真的应该用乔希的更新来更新你的版本,这样下一个阅读这个的人就可以有一个工作样本。我评论了各种元素并清理了一点,完整的答案可以在这里看到:codesandbox.io/s/pass-state-up-and-props-down-wb03r?file=/src/…
【解决方案2】:

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

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

【讨论】:

  • 这个问题在 React 中很容易通过回调 props 解决,而不是引入一个全新的库。此外,不建议使用 localStorage 传播更改,因为可能难以理解这些值的保存位置,并且会破坏数据的单向流动。
  • 谢谢三顿。我已经开始阅读 Redux 文档,但我认为它现在有点不合我意:)
猜你喜欢
  • 2017-11-17
  • 2019-06-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-10
  • 2021-10-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多