Я не могу использовать setState правильно, чтобы изменить значение - PullRequest
0 голосов
/ 07 января 2019

Я пытаюсь использовать setState для изменения значения в состоянии компонентов (personId) со значением (pid), которое я получаю из render ().

Существует три сценария внутри этого компонента. Это все те же сценарии, но с небольшими изменениями в зависимости от того, что я получаю от API-вызова с Axios.

Я изменяю состояние внутри componentDidMount, которое, я думаю, запускается один раз при открытии компонента, я также пытался изменить состояние внутри componentDidUpdate, что затем вызывает бесконечный цикл.

Я также исключил кусок кода, который на самом деле не имеет ничего общего с этой проблемой, просто чтобы сделать ее несколько более чистой.

class SearchPage extends React.Component {

    state = {
        personId: '',
        person_results: [],
    }

        componentDidMount(){
            //this.props.fetchPersonInfo(this.state.personId)
            let pid;
            if(this.props.results.length > 0){
                if (this.props.results[0].results[0].media_type === 'person'){
                    this.setState({person_results: this.props.results[0].results});
                    pid = this.state.person_results.id;
                } else if (this.props.results[0].results[1].media_type === 'person'){
                    this.setState({person_results: this.props.results[0].results})
                    pid = this.state.person_results.id;
                } else if (this.props.results[0].results[2].media_type === 'person'){
                    this.setState({person_results: this.props.results[0].results})
                    pid = this.state.person_results.id
                }
            }
            this.setState({
                personId: pid,
            })
        }


    render(){
            if (this.props.results.length > 0){
                if (this.props.results[0].results[0].media_type === 'person'){
                    console.log(this.props.results[0].results[0]);
                    console.log(this.state.person_results);
                    return (
                        <div className='.col-md-4 search-container'>
                                <div className='search-results-person'>
                                    <h5 className='search-title'>{this.state.person_results.name}</h5>
                                    <img className='search-image' src={`${img_url}${this.state.person_results.profile_path}`} alt={this.state.person_results.name} />
                                </div>
                        </div>
                    )
                } else if (this.props.results[0].results[1].media_type === 'person'){
                    console.log(this.state.person_results);
                    return (
                        <div className='.col-md-4 search-container'>
                                <div className='search-results-person'>
                                    <h5 className='search-title'>{this.state.person_results.name}</h5>
                                    <img className='search-image' src={`${img_url}${this.state.person_results.profile_path}`} alt={this.state.person_results.name} />
                                </div>
                        </div>
                    )
                } else if (this.props.results[0].results[2].media_type === 'person'){
                    console.log(this.state.person_results);
                    return (
                        <div className='.col-md-4 search-container'>
                                <div className='search-results-person'>
                                    <h5 className='search-title'>{this.state.person_results.name}</h5>
                                    <img className='search-image' src={`${img_url}${this.state.person_results.profile_path}`} alt={this.state.person_results.name} />
                                </div>
                        </div>
                    )
                }
            }
            return (
                <div className='container-fluid'>
                        <div className='row'>
                                {results}
                                {this.state.personId}
                                {this.state.person_results}
                        </div>
                </div>
            )
        }
    }

const mapStateToProps = (state) => {
    return {
        results: state.movTv.results,
        person: state.movTv.personInfo
    }
}

export default connect(mapStateToProps, { fetchPersonInfo })(SearchPage);

РЕДАКТИРОВАТЬ: Обновлен код для компонента.

Ответы [ 2 ]

0 голосов
/ 07 января 2019

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

Дополнительное замечание: изначально кажется странным, что вы будете звонить setState после того, как компонент "смонтирован", но реагирует на любые вызовы setState в componentDidMount до того, как он действительно отобразит

Это будет выглядеть примерно так -

class SearchPage extends React.Component {

    state = {
        personId: '',
        person_results: []
    }

        componentDidMount(){
            let pid;
            if (this.props.results.length > 0){
                if (this.props.results[0].results[0].media_type === 'person'){
                    person_results = this.props.results[0].results[0];
                    pid = person_results.id;
                } else if (this.props.results[0].results[1].media_type === 'person'){
                    person_results = this.props.results[0].results[1];
                    pid = person_results.id;
                } else if (this.props.results[0].results[2].media_type === 'person'){
                    person_results = this.props.results[0].results[2];
                    pid = person_results.id;
                }
            }
            this.setState({
                personId: pid,
                person_results
            })
        }


    render(){

            return (
                <div className='container-fluid'>
                        <div className='row'>
                                {this.state.personId}
                                {this.state.person_results}
                        </div>
                </div>
            )
        }
    }

const mapStateToProps = (state) => {
    return {
        results: state.movTv.results,
        person: state.movTv.personInfo
    }
}

export default connect(mapStateToProps, { fetchPersonInfo })(SearchPage);

это может быть реорганизовано больше, но это даст вам представление о том, с чего начать

0 голосов
/ 07 января 2019

Ваши переменные pid и person_results относятся к модулю, то есть они определены "на том же уровне", что и ваш компонент SearchPage. Рекомендуется определять const s на этом уровне только при использовании React (например, URL вашего изображения). В настоящее время React не может прослушивать изменения этих переменных и, следовательно, не будет обновлять состояние в таких строках:

person_results = this.props.results[0].results[0];
pid = person_results.id;

Если вы хотите, чтобы React обновлял компонент при изменении переменной, вам следует вместо этого определить эти переменные как свойства состояния внутри конструктора:

class SearchPage extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      person_results = /*...*/,
      pid: /*...*/
    }
  }

  /*...*/

}

, а затем соответствующим образом рефакторинг вашего кода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...