Как передать состояние в React из index.js дочерним элементам без использования Redux? - PullRequest
0 голосов
/ 03 июля 2018

У меня есть пример приложения 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 голосов
/ 03 июля 2018

Вы должны вручную пропустить подпорки.

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

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

Redux разработан для тех случаев, когда вы просто передаете и пересылаете реквизит.

Как указано на их сайте, их мотивация.

Управлять этим постоянно меняющимся состоянием сложно. Если модель может обновить другую модель, то представление может обновить модель, которая обновит другую модель, и это, в свою очередь, может привести к обновлению другого представления. В какой-то момент вы больше не понимаете, что происходит в вашем приложении, поскольку вы потеряли контроль над тем, когда, почему и как его состояние. Когда система непрозрачна и недетерминирована, трудно воспроизвести ошибки или добавить новые функции.

0 голосов
/ 03 июля 2018

Ну, в этом случае вам нужно использовать 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, что важно, что вы получили идея.

0 голосов
/ 03 июля 2018

Просто передавая состояние через реквизит, 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>
    );
  }
}
...