更新父组件后,React子状态不会更新

时间:2017-09-12 11:55:10

标签: reactjs components

我尝试通过父组件更新子center组件的BaseMap道具。即使父组件状态得到更新(我可以读取console.log中的新更新属性),它也不会传递给子属性。

我尝试的最后一件事是componentWillReceiveProps方法。它仍然无法运作。

这是我的代码:

const google = window.google;
let geocoder = new google.maps.Geocoder();

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      avatar: '',
      username: 'someUse03',
      realName: '',
      location: '',
      followers: '',
      following: '',
      repos: '',
      address: '',
      }
  }

  render() {
    return (
      <div>
        <SearchBox fetchUser={this.fetchUser.bind(this)}/>
        <Card data={this.state} />
        <BaseMap />
      </div>
    );
  }

  fetchApi(url) {
    fetch(url)
      .then((res) => res.json())
      .then((data) => {
        this.setState({
          avatar: data.avatar_url,
          username: data.login,
          realName: data.name,
          location: data.location,
          followers: data.followers,
          following: data.following,
          repos: data.public_repos,
          address: geocoder.geocode({'address': data.location}, function(results, status) {
            if (status == 'OK') {
              var coords = [];
              var results = results.map((i) => {
                i.geometry.location = i.geometry.location
                          .toString()
                          .replace(/[()]/g, '')
                          .split(', ');
                coords.push(i.geometry.location[0], i.geometry.location[1]);
                results = coords.map((i) => {
                  return parseInt(i, 10)
                });
                return results;
              });
            } else {
              alert('Geocoding was not successfull because ' + status)
            }
          })
        })
      });
  }

  fetchUser(username) {
    let url = `https://api.github.com/users/${username}`;

    this.fetchApi(url);
  }

  componentDidMount() {
    let url = `https://api.github.com/users/${this.state.username}`;

    this.fetchApi(url);
  }

}

export default App;

这是子组件:

BaseMap extends React.Component {
        constructor(props) {
            super(props);
            this.state = {
                center: [41, 21],
            }
        }

        componentWillReceiveProps(nextProps) {
            this.setState({ center: nextProps.address});
        }

        render() {
            return (
                <Col md={10} mdPull={1}>
                    <div className="map">
                        <GoogleMap
                        bootstrapURLKeys={'AIzaSyBhzwgQ3EfoIRYT70fbjrWASQVwO63MKu4'}
                        center={this.state.center}
                        zoom={11}>
                        </GoogleMap>
                    </div>
                </Col>
            );
        }
    }

1 个答案:

答案 0 :(得分:2)

您正在获取render方法。这是一个很大的 NO NO 而是在componentDidMount life cycle method

中执行此操作

另一件可能与您的问题有关的事情是,数组是引用类型,这意味着如果你改变它们,它们仍然指向内存中的相同引用。这可能是Reconciliation and diff algorithm of react确定州是否确实发生变化的问题 当您想要更改或返回新阵列时,您只需使用ES6 spread operator

const nextArray = [...nextProps.address]
this.setState({ center: nextArray });

修改
好吧,我忘了在这里提到最重要的部分:) 您没有将任何道具传递给<BaseMap />,因此您无法在componentWillReceiveProps中获得任何有用的数据。