Подтвердить что ты не робот

Реагировать дочерний компонент, не обновляющийся после изменения состояния родителя

Я пытаюсь сделать хороший компонент ApiWrapper для заполнения данных в различных дочерних компонентах. Из всего, что я прочитал, это должно работать: https://jsfiddle.net/vinniejames/m1mesp6z/1/

class ApiWrapper extends React.Component {

  constructor(props) {
    super(props);

    this.state = {
      response: {
        "title": 'nothing fetched yet'
      }
    };
  }

  componentDidMount() {
    this._makeApiCall(this.props.endpoint);
  }

  _makeApiCall(endpoint) {
    fetch(endpoint).then(function(response) {
      this.setState({
        response: response
      });
    }.bind(this))
  }

  render() {
    return <Child data = {
      this.state.response
    }
    />;
  }
}

class Child extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      data: props.data
    };
  }

  render() {
    console.log(this.state.data, 'new data');
    return ( < span > {
      this.state.data.title
    } < /span>);
  };
}

var element = < ApiWrapper endpoint = "https://jsonplaceholder.typicode.com/posts/1" / > ;

ReactDOM.render(
  element,
  document.getElementById('container')
);

Но по какой-то причине кажется, что дочерний компонент не обновляется при изменении состояния родителя.

Я что-то пропустил?

4b9b3361

Ответ 1

В коде есть две проблемы.

Начальное состояние вашего дочернего компонента устанавливается из реквизита.

this.state = {
  data: props.data
};

Цитата из этого SO-ответа:

Передача исходного состояния компоненту как prop является анти-шаблоном потому что метод getInitialState (в нашем случае constuctor) называется только первым компонент. Никогда больше. Это означает, что если вы повторно компонент, передающий другое значение как prop, компонент не будет реагировать соответственно, потому что компонент будет поддерживать состояние с первого раза это было сделано. Он очень подвержен ошибкам.

Итак, если вы не можете избежать такой ситуации, идеальным решением является использование метода componentWillReceiveProps для прослушивания новых реквизитов.

Добавление приведенного ниже кода к вашему дочернему компоненту решит вашу проблему с реиндексированием дочерних компонентов.

componentWillReceiveProps(nextProps) {
  this.setState({ data: nextProps.data });  
}

Вторая проблема связана с fetch.

_makeApiCall(endpoint) {
  fetch(endpoint)
    .then((response) => response.json())   // ----> you missed this part
    .then((response) => this.setState({ response }));
}

И вот рабочая скрипка: https://jsfiddle.net/o8b04mLy/

Ответ 2

Есть некоторые вещи, которые вам нужно изменить.

Когда fetch получит ответ, это не json. Я искал, как я могу получить этот json, и я обнаружил эту ссылку .

С другой стороны вам нужно подумать, что функция constructor вызывается только один раз.

Итак, вам нужно изменить способ получения данных в компоненте <Child>.

Здесь я оставил код примера: https://jsfiddle.net/emq1ztqj/

Я надеюсь, что это поможет.