使用redux操作更新状态后,React组件不会更新

时间:2019-03-27 13:26:27

标签: reactjs redux react-redux react-thunk

/ keywordsActions

import { UPDATE_KEYWORDS } from "./actionTypes";
import queryString from "query-string";

const keywordsArrayFromUrl = () => {
  const query = queryString.parse(window.location.search);
  if (query.keywords) {
    const removeDuplicate = new Set(query.keywords.split(" "));
    return Array.from(removeDuplicate);
  }

  return [];
};

export function updateKeywords() {
  return async dispatch => {
    dispatch({
      type: UPDATE_KEYWORDS,
      payload: await keywordsArrayFromUrl()
    });
  };
}

/ keywordReducer

import { UPDATE_KEYWORDS } from "../actions/actionTypes";

export default function(state = [], action) {
  switch (action.type) {
    case UPDATE_KEYWORDS:
      return action.payload;
    default:
      return state;
  }
}

/ SearchBar-React组件

import React, { Component } from "react";
import { withRouter } from "react-router-dom";
//Redux
import { connect } from "react-redux";
import { updateKeywords } from "../store/actions/KeywordsAction";

class Searchbar extends Component {
  constructor(props) {
    super(props);
    this.state = {
      keywords : this.props.keywords
      keywordsString: this.props.keywords.join(" ")
    };
  }

  componentDidMount() {
    this.props.updateKeywords();
    console.log(this.props)
    setTimeout(() => console.log(this.props), 10);
  }

  _handleChange = e => {
    this.setState({ keywordsString: e.target.value });
  };

  _handleSearch = value => {
    this.setState({ keywordsString: value });
    this.props.history.push(`/search?keywords=${value}`);
  };

  render() {
    return (
      <Search
        className="Searchbar"
        placeholder="Cauta prin iBac..."
        value={this.state.keywordsString}
        onChange={this._handleChange}
        onSearch={this._handleSearch}
      />
    );
  }
}

const mapStateToProps = state => {
  return {
    keywords: state.keywords
  };
};

export default connect(
  mapStateToProps,
  { updateKeywords }
)(withRouter(Searchbar));

我想将关键字从Url保存到商店,然后将其传递到搜索栏状态。

但是我不明白这一点:

  componentDidMount() {
    this.props.updateKeywords();
    console.log(this.props); // this.props.keywords is empty
    setTimeout(() => console.log(this.props), 10); // After 10 ms this.props.keywords is no empty 
  }

10毫秒后,Searchbar的道具会更新,但组件不会再次呈现。

很抱歉,我真的是React / Redux的新手。请让我知道我在做什么错。谢谢大家!

更新:

  componentDidMount() {
    this.props.updateKeywords();
    setTimeout(() => {
      this.setState({
        keywordsString: this.props.keywords.join(" ")
      });
    }, 0);
  }

此代码也可以正常工作,但是其他代码无法正常工作

componentDidMount() {
    this.props.updateKeywords();
      this.setState({
        keywordsString: this.props.keywords.join(" ")
      });
  }

1 个答案:

答案 0 :(得分:0)

原因是componentDidMount在挂载时仅被调用一次。您要查找的是componentShouldUpdatecomponentDidUpdaterender函数,当您的组件从redux接收更新状态时,将全部调用这些函数。您可以在此处阅读有关这些功能的更多信息。

https://reactjs.org/docs/react-component.html#updating