Компонент React не обновляется после обновления состояния с помощью действия приставки - PullRequest
1 голос
/ 27 марта 2019

/wordsActions

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 Component

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 мс реквизиты панели поиска обновляются, но компонент не визуализируется снова.

Извините за мой вопрос, я действительно новичок в 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 голосов
/ 27 марта 2019

Причина в том, что componentDidMount вызывается только один раз при монтировании. То, что вы ищете, это либо componentShouldUpdate или componentDidUpdate, либо функция render, все из которых вызываются, когда ваш компонент получает обновленное состояние от избыточного числа. Вы можете прочитать здесь для получения дополнительной информации о том, что делают эти функции.

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

...