如何不使用Redux将React中的状态从index.js传递到子元素?

时间:2018-07-03 05:21:47

标签: reactjs state state-management

我有一个示例React应用,该应用在首页上显示了项目。我创建的组件为Index> Projects> Project

我在Index.js中的代码:

class App extends React.Component {
    render() {
        return (
            <Router>
                <div>
                    <Header/>
                    <Projects/>
                    <Footer/>
                </div>
            </Router>
        );
    }
}

我在Projects.js中的代码:

export class Projects extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            projects: [
                {
                    name: "Smithsonian Institute",
                    desc: "Description goes here",
                    img: "https://mir-s3-cdn-cf.net//max_1200/da.jpg"
                },
                {
                    name: "Beauty Inc Next Dimension",
                    desc: "Description goes here",
                    img: "https://mir-s3-cdn-cf.net/15d.jpg"
                },
                {
                    name: "Beyond the Pale Blue Dot",
                    desc: "Description goes here",
                    img: "https://mir-s3-cdn-cf.net/5e22.jpg"
                }
            ]
        };
    }

    render() {
        return (
            <Project data={this.state.projects} />
        );
    }
};

我在Project.js中的代码:

export class Project extends React.Component {
    render() {
        return (
            <section className="projects bg-ash">
                {this.props.data.map((item,i)=>
                    <div className="container work-item" key={i}>
                        <div className="row justify-content-center align-items-center">
                            <div className="col-12 col-md-6 col-lg-5">
                                <a href=""><img src={item.img} className="img-fluid rounded" alt={item.name}/></a>
                            </div>
                            <div className="col-12 col-md-6 col-lg-5 image-box">
                                <h5>{item.name}</h5>
                                <p>{item.desc}</p>
                            </div>
                        </div>
                    </div>
                )}
            </section>
        );
    }
};

我需要在this.state = { projects: [] }中拥有这个index.js数据对象,并将其通过Projects.js传递到Project.js

主要目标是在没有Redux的情况下管理状态。最好的方法是什么?

3 个答案:

答案 0 :(得分:0)

只需通过道具传递状态,就不需要Redux:

示例:CodeSandbox

index.js

import React from "react";
import ReactDOM from "react-dom";
import ListItem from "./ListItem";

import "./styles.css";

class App extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      projects: [
        {
          name: "Smithsonian Institute",
          desc: "Description goes here",
          img: "https://mir-s3-cdn-cf.net//max_1200/da.jpg"
        },
        {
          name: "Beauty Inc Next Dimension",
          desc: "Description goes here",
          img: "https://mir-s3-cdn-cf.net/15d.jpg"
        },
        {
          name: "Beyond the Pale Blue Dot",
          desc: "Description goes here",
          img: "https://mir-s3-cdn-cf.net/5e22.jpg"
        }
      ]
    };
  }

  render() {
    return (
      <div className="App">
        <ListItem items={this.state.projects} />
      </div>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

ListItem.js

import React from "react";
import Item from "./Item";

export default class ListItem extends React.Component {
  render() {
    return (
      <ul>
        {this.props.items.map((item, index) => (
          <Item data={item} key={index} />
        ))}
      </ul>
    );
  }
}

Item.js

import React from "react";

export default class Item extends React.Component {
  render() {
    const { data } = this.props;
    return (
      <li>
        <div>
          <h3>{data.name}</h3>
          <p>{data.desc}</p>
          <img src={data.img} />
        </div>
      </li>
    );
  }
}

答案 1 :(得分:0)

您必须手动传递道具。

<Projects
  projects={this.state.projects}
/>

<Project
  projects={this.props.projects}
/>

Redux专为此类情况而设计,当您发现自己只是传递和转发道具时。

如他们网站上所述,他们的动机。

  

管理这种不断变化的状态非常困难。如果一个模型可以更新另一个模型,那么一个视图可以更新一个模型,该模型可以更新另一个模型,这又可能导致另一个视图更新。在某些时候,您不再了解应用程序中发生的情况,因为您无法控制其状态的时间,原因和方式。当系统是不透明且不确定的系统时,很难重现错误或添加新功能。

答案 2 :(得分:0)

在这种情况下,您需要使用liftStateUp,可以将projects的状态提升为index,然后在Projects.js内部将项目作为道具传递给Project.js

Index.js:

class App extends React.Component {
      constructor(props) {
    super(props);

    this.state = {
      newProjects: undefined;
    };
  }

  receiveFunction = (oldProject) => {
    this.setState({ newProjects: oldProject})
  }

        render() {
            return (
                <Router>
                    <div>
                        <Header/>
                        <Projects receiveState={this.receiveFunction} newProjects={this.state.newProjects} />
                        <Footer/>
                    </div>
                </Router>
            );
        }
    }

Projects.js:

    export class Projects extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            projects: [
                {
                    name: "Smithsonian Institute",
                    desc: "Description goes here",
                    img: "https://mir-s3-cdn-cf.net//max_1200/da.jpg"
                },
                {
                    name: "Beauty Inc Next Dimension",
                    desc: "Description goes here",
                    img: "https://mir-s3-cdn-cf.net/15d.jpg"
                },
                {
                    name: "Beyond the Pale Blue Dot",
                    desc: "Description goes here",
                    img: "https://mir-s3-cdn-cf.net/5e22.jpg"
                }
            ]
        };
    }

    liftStateUp = () =>{ // call this function whenever you want to pass the state to parent component
    let projects = this.state.projects;
      this.props.receiveState(projects);
    }

    componentDidUpdate(prevProps, prevState){ // you can fire liftStateUp when every change in projects state
        if(prevState.projects !== this.state.projects){
            this.liftStateUp();
        }
    }

    render() {
        return (
            <Project data={this.props.newProjects ? this.props.newProjects : this.state.projects} />
        );
    }
};
  

注意:liftStateUp函数需要启动,因此我使用componentDidUpdate来监听项目状态是否发生变化,然后它将被传递到索引页,或者例如,您可以使用onClick方法,知道这个想法很重要。