在React中将状态从一个组件设置为另一个组件的最佳实践方法

时间:2018-10-28 19:44:44

标签: javascript reactjs

我是从最佳实践的角度提出这个问题的-我在这里找到的答案是关于单个代码库的更具体问题。如果已被回答,我很乐意朝着正确的方向前进;如果我的尝试不被视为良好实践,我很乐意以另一种方式展示-我可能误解了一些概念...

我正在学习React,并正在使用它构建一个简单的应用程序。 主要是为了保持代码整洁,我创建了两个文件。 第一个文件-我从组件内部访问API,并从组件状态渲染一些数据。 第二个文件-我想在第一个文件中使用来自组件状态的相同信息,并在第二个文件中将其用作道具。

下面是一个简化的示例。

第一个文件:

import React, { Component } from 'react';
import SecondComponent from './SecondComponent';

function DisplayFirstData (props) {
  return (
    {props.data}
}

class FirstComponent extends Component {
  constructor(props) {
    super(props);
    this.state = {
      myData: something,
    }
  }
  render() {
    <DisplayFirstData data={this.state.myData} />
  }
}

第二部分:

import React, { Component } from 'react';

function DisplaySecondData (props) {
  return (
    {props.data}
}

class SecondComponent extends Component {
  constructor(props) {
    super(props);
    this.state = {
      // State object from the first component file
    }
  }
  render() {
    <DisplaySecondData data={this.state.myData} />
  }
}

3 个答案:

答案 0 :(得分:2)

我不确定您要完成什么,但是我建议两件事:

  • 由于<DisplayFirstData /><DisplaySecondData />的作用完全相同,因此您应将它们移至新文件并命名为<DisplayData />(我说“ it”是因为您最终只会得到一个组件)。每当您需要时,只需执行:import DisplayData from 'path/to/file
  • 现在您有了<DisplayData />组件,将一个组件包装在<FirstComponent /><SecondComponent />周围,将其命名为<ParentComponent />。将所有状态从<FirstComponent />移到<ParentComponent />。如果您的数据是从其他地方获取的,则也将获取代码也移到这里。

之后,您只需要将状态向下传递到<FirstComponent /><SecondComponent />。您可以直接在<SecondComponent />中以道具的形式访问状态,也可以从道具中初始化其状态。有关更多信息,请阅读this

总体而言,您的代码应如下所示:

import React, { Component } from 'react';
import { FirstComponent, SecondComponent } from 'path/to/folder/contains/the/files';

class ParentComponent extends Component {
  state = {
    //Move your states here
  }
  //Move your fetching code here
  render() {
    const { data } = this.state; 
    return(
      <>
        <FirstComponent data={data} />
        <SecondComponent data={data} />
      </>
    );
  }
}

<SecondComponent />中:

import React from 'react';
import DisplayData from 'path/to/file';

export default SecondComponent = props => {
  const { data } = props.data;

  return(
    <DisplayData data={data} />
  )
}

答案 1 :(得分:1)

一种常见的技术是lift state up to the first common ancestor同时使用两个组件,并将其作为道具传递给两个组件。

示例

function getData() {
  return new Promise(resolve => setTimeout(() => resolve(42), 1000));
}

class FirstComponent extends React.Component {
  render() {
    return <div>{this.props.data}</div>;
  }
}

class SecondComponent extends React.Component {
  render() {
    return <div>{this.props.data}</div>;
  }
}

class App extends React.Component {
  state = { data: null };

  componentDidMount() {
    getData().then(data => {
      this.setState({ data });
    });
  }

  render() {
    const { data } = this.state;
    
    if (data === null) {
      return null;
    }
    return (
      <div>
        <FirstComponent data={data} />
        <SecondComponent data={data} />
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

答案 2 :(得分:0)

如评论中所指出的,一种通用技术是将状态提升到两个组件的第一个共同祖先,并将其作为道具传递给两个组件。

这是您的顶级(父级)组件(用于保持状态的基于类的组件),然后通过道具将该数据传递给子级:

import DisplayFirstData from "./DisplayFirstData";
import DisplaySecondData from "./DisplaySecondData";

class App extends Component {
  state = { myData: "something" };
  render() {
    return (
      <div>
        <DisplayFirstData data={this.state.myData} />
        <DisplaySecondData data={this.state.myData} />
      </div>
    );
  }
}

在其中,您将通过prop数据将在状态下已初始化的数据传递给正在调用<DisplayFirstData />的第二个组件,而对于<DisplaySecondData />则是相同的

这是您的子组件1:

const DisplayFirstData = props => (
  <div>
    <h2>Access your data here via props</h2>
    <p>{props.data}</p>
  </div>
);

export default DisplayFirstData;

这是您的子组件2:

const DisplaySecondtData = props => (
  <div>
    <h2>Access your data here via props</h2>
    <p>{props.data}</p>
  </div>
);

export default DisplaySecondData;

关于codeandbox ...的工作示例:https://codesandbox.io/s/407oq1znx

作为旁注:我不知道为什么您需要两个不同的组件来完成完全相同的操作,但是无论如何,上面的示例是实现此目的的方法...另外,在您的学习过程中,您应该了解并爱上更高的order component patterncontext API(我怀疑当您不断尝试构建它时,您将需要它们...)