从道具写到当地州

时间:2018-10-10 05:53:24

标签: reactjs redux react-redux fetch

我知道这个问题相当简单,但是我无法解决,我需要您的帮助。

我尝试了所有类似问题的解决方案,但对我来说不起作用

最重要的是,当我安装组件时,我运行fetch并从我的API中获得了文章列表,但这并不适合我,因为我没有将它们保存在本地状态。

此外,我对React的深入了解,还有两个问题: 1)当我浏览页面时,当我返回到文章页面时,结果的数量以算术级数重复,据我所知,这是我将文章保留在道具中的问题,但是我需要保存它在当地状态。 2)从此我的第二个问题到期了。我尝试了所有操作,但是为了以后应用this.state.articles.map,我无法做props.articles-> state.articles

//动作

import {FETCH_ALL_ARTICLES} from "../constants";


export const fetchAllArticles = () => {
  return (dispatch) => {
    let headers = {"Content-Type": "application/json"};

  return fetch("/api/articles/", {headers, })
    .then(res => {
       if (res.status < 500) {
         return res.json().then(data => {
           return {status: res.status, data};
       })
       } else {
         console.log("Server Error!");
         throw res;
    }
  })
  .then(res => {
    if (res.status === 200) {
      return dispatch({type: FETCH_ALL_ARTICLES, articles: res.data});
    }
  })
}
};

//组件

import React, { Component } from 'react';
import {connect} from 'react-redux';
import {Link} from 'react-router-dom';

import {articles} from "../actions";


class Home extends Component {

constructor(props) {
  super(props);
  this.state = {
      articles: []
  }
  console.log(this.props.articles)
};

componentDidMount() {
    this.props.fetchAllArticles()
};

render() {
    return (
        <div>
            <Link to='/notes'>Notes</Link>
            <h2>All articles</h2>
            <hr />
            <table>
                <tbody>
                    {this.state.articles.map((article, id) => (
                        <tr key={`article_${id}`}>
                            <td>{article.headline}</td>
                            <td>{article.description}</td>
                            <td>{article.created}</td>
                            <td>{article.author.username}</td>
                            <td>{article.image}</td>
                        </tr>
                    ))}
                </tbody>
            </table>
        </div>
    )
  }
}

const mapStateToProps = state => {
   return {
      articles: state.articles,
   }
};

const mapDispatchToProps = dispatch => {
    return {
       fetchAllArticles: () => {
           dispatch(articles.fetchAllArticles())
       }
    }
};

export default connect(mapStateToProps, mapDispatchToProps)(Home);

//减速器

import {FETCH_ALL_ARTICLES} from "../constants";


const initialState = [];

export default function articles(state=initialState, action) {

switch (action.type) {

  case FETCH_ALL_ARTICLES:
    return [...state, ...action.articles];

  default:
    return state;
}
}

4 个答案:

答案 0 :(得分:2)

您的问题尚不清楚,但我将尝试根据标题“从道具写到本地状态”进行解释。

您可以利用以下组件生命周期来实现这一目标

componentWillReceiveProps(nextProps) { 
  if (nextProps.articles) {
    this.setState({ articles: nextProps.articles });
  }
}

基本上,只要对此组件有更新,此生命周期方法componentWillReceiveProps都会在重新呈现之前被调用,因此我们可以在此处调用setState并将其保存到本地状态。

  

当我返回到文章页面时,结果数以算术级数重复

如果正确处理减速器,则不应发生这种情况。例如,从API获取文章后,清除数组,然后仅存储从API接收的值。但是,那当然取决于您要实现的目标

答案 1 :(得分:1)

您可以直接在render函数中从this.prop.articles渲染文章。

import React, { Component } from 'react';
import {connect} from 'react-redux';
import {Link} from 'react-router-dom';

import {articles} from "../actions";


class Home extends Component {

componentDidMount() {
    this.props.fetchAllArticles()
};

render() {
    return (
        <div>
            <Link to='/notes'>Notes</Link>
            <h2>All articles</h2>
            <hr />
            <table>
                <tbody>
                    {this.props.articles.map((article, id) => (
                        <tr key={`article_${id}`}>
                            <td>{article.headline}</td>
                            <td>{article.description}</td>
                            <td>{article.created}</td>
                            <td>{article.author.username}</td>
                            <td>{article.image}</td>
                        </tr>
                    ))}
                </tbody>
            </table>
        </div>
    )
  }
}

const mapStateToProps = state => {
   return {
      articles: state.articles,
   }
};

const mapDispatchToProps = dispatch => {
    return {
       fetchAllArticles: () => {
           dispatch(articles.fetchAllArticles())
       }
    }
};

export default connect(mapStateToProps, mapDispatchToProps)(Home);

答案 2 :(得分:1)

每次安装组件时,您都会获取所有文章。 提取所有文章后,将它们添加到现有的Redux状态:

return [...state, ...action.articles];

要解决此问题,您可以丢弃旧文章,而不要保留它们:

return [...action.articles];

或者您可以避免获取已获取的文章:

componentDidMount() {
    if (!this.props.articles || this.props.articles.length === 0) {
        this.props.fetchAllArticles()
    }
};

您无需对本地状态做任何事情。您的Redux状态是事实的唯一来源。将数据的另一个副本保持在本地状态是没有用的。

答案 3 :(得分:0)

您的问题很简短,但是据我了解,您正在寻求通过道具将数据从父组件传递到子组件,然后将其存储到本地状态。

为此,您需要将构造函数添加到子组件中,并分配道具以使其状态类似。

import React,{Component} from 'react';
class ChildComponent extends Component{
  constructor(props){
    super(props);
    this.state={
      name: props.name,
      email: props.email      
    }
  }
  ..........
  // your child component logic

}

将数据通过父组件传递,例如

<ChildComponent name={this.state.name} email={this.state.email} />