当我们的道具发生变化时,我们如何在react.js上更新我们的组件?

时间:2017-10-12 06:26:02

标签: javascript reactjs

每当我的道具改变时,我愿意改变我的页面。我的道具很重要,因为它从API中检索与prop.id相对应的特定数据。现在,我对prop.id的API请求在componentWillMount()部分,因此它只运行一次。我希望在我的prop.id改变时改变它,我想我必须使用

componentWillReceiveProps(newProps) {    
  console.log('Component WILL RECIEVE PROPS!')
}

shouldComponentUpdate(newProps, newState) {
  return true;
}

每当道具改变时更新我的​​页面,但我不确定这是如何工作的。我认为当prop更改时,componentWillReceiveProps会运行,但我不知道如何更改shouldComponentUpdate以使我的prop更改后页面不断更新。

任何提示?

编辑:

指向详细信息/ ID页面的链接

        return data.map((eachData, index) => {
            return (  <Link to={{ pathname: '/details/' + parseID(eachData.url) }}><PokemonInfo poke={ eachData } key={ index } /></Link> );
        });
    };

继续&#34; / details /&#34; + parseID(eachData.url),它只是相应数据的id。 Next和Prev部分应该呈现id为+ 1的页面。它可以工作,但更新会延迟,我必须双击才能获得实际的道具。

class PokemonDetails extends React.Component {

    constructor() {
        super();


        this.state = {


            pokemon: [],
            imgurl: '',
            abilities: [],
            types: []
        };


    };


    componentWillMount() {
    // Called first time the comp is loaded right before the comp is added to the page
        console.log('Component WILL MOUNT!')
        console.log("passed" , this.props.match.params.id)
        var url = "https://pokeapi.co/api/v2/pokemon/" + this.props.match.params.id; 

        axios.get(url)

        .then((response) => {
            // setState re-renders component
            this.setState({
                pokemon: response.data,
                imgurl: response.data.sprites.front_default,
                abilities: response.data.abilities,
                types: response.data.types,
            })

            console.log(this.state.pokemon)
            console.log('url', this.state.imgurl)
        })

            .catch((error) => {
                console.log(error);
        })
    }

    componentWillReceiveProps(newProps) {    
      console.log('Component WILL RECIEVE PROPS!')
        console.log("passed" , this.props.match.params.id)
        var url = "https://pokeapi.co/api/v2/pokemon/" + this.props.match.params.id; 

        axios.get(url)

        .then((response) => {
            // setState re-renders component
            this.setState({
                pokemon: response.data,
                imgurl: response.data.sprites.front_default,
                abilities: response.data.abilities,
                types: response.data.types,
            })

            console.log(this.state.pokemon)
            console.log('url', this.state.imgurl)
        })

            .catch((error) => {
                console.log(error);
        })
    }

    shouldComponentUpdate(newProps, newState) {
      if(newProps.match.params.id != this.props.match.params.id) return true;
      return false;
    }

    render() {

        let abilities = this.state.abilities.map( (ability, idx) => {
            return(
                <Label key = { idx }>
                    { ability.ability.name }
                </Label>
            )
        });

        let types = this.state.types.map( (type, idx) => {
            return(
                <Label key = { idx }>
                    { type.type.name }
                </Label>
            )
        });

        return (

                <div className="Home">
                    <h1>Gotta catchem all!</h1>
                    <div className="Menu">
                        <Link to="/"><span className="menuSpan">Search</span></Link >
                        <Link to="/gallery"><span className="menuSpan">Gallery</span></Link >

                        </div>              
                <div>
                    <img src= { this.state.imgurl } />
                    <h2>{ this.state.pokemon.name }</h2>

                        <h3>
                            <Link onChange = { this.handleChange } to={{ pathname: '/details/' + (parseInt(this.props.match.params.id) - 1) }}><span>Prev</span></Link>
                            Pokedex #{ this.state.pokemon.id }
                            <Link onChange = { this.handleChange } to={{ pathname: '/details/' + (parseInt(this.props.match.params.id) + 1) }}><span>Next</span></Link>
                        </h3>
                        <h3>
                            Height { this.state.pokemon.height }
                        </h3>
                        <h3>
                            Weight <label>{ this.state.pokemon.weight }</label>
                        </h3>       
                        <h4>Abilities</h4>
                        { abilities }
                        <h4>Type(s)</h4>
                        { types }


                </div>
            </div>

        );
    }
}

1 个答案:

答案 0 :(得分:1)

您可以在shouldComponentUpdate中设置条件。当shouldComponentUpdate返回true值时,系统会调用您组件的render函数。所以你可以做这样的事情。

shouldComponentUpdate(newProps, newState) {
  if(newProps.id!==props.id) {
      return true
  }
  return false;
}