【问题标题】:Initial state of component not updating on first render组件的初始状态在第一次渲染时未更新
【发布时间】:2018-02-04 23:19:36
【问题描述】:

组件从其父组件获取两个 props(分别为加密和加密)。

我正在启动一个状态属性selectedCrypto,它负责用this.props.crypto 显示第一个输入的值。

这个想法是,当用户单击列表中的一个密码时,它应该使用所选密码的名称呈现输入,但这不会发生。 道具收到很好。我可以在组件上 console.log 它显示当前的加密,但由于某种原因,组件的状态在第一次渲染时没有得到它。

转换器组件:

import React, {Component} from 'react';
import Select from 'react-select';
import sortBy from 'sort-by';
import numeral from 'numeral';
import styles from '../../style/css/select_style.css';

class Conversor extends Component {
    constructor(props){
        super(props);

        this.state = {
            selectedCrypto: props.crypto || {},
            cryptoToConvert: {name: 'USD'},
            amount: 0,
            result: 0
        }
    }

    updateValue (newValue) {
        let result = this.conversorFunc(this.state.amount, newValue, this.state.cryptoToConvert);
        this.setState({
            selectedCrypto: newValue,
            result
        });
    }

    updateValue2(newValue){
        let result = this.conversorFunc(this.state.amount, this.state.selectedCrypto, newValue);
        this.setState({
            cryptoToConvert: newValue,
            result
        });
    }

    converterHandler(event){

        let inputCrypto = this.state.selectedCrypto;
        let ouputCrypto = this.state.cryptoToConvert;

        let result = this.conversorFunc(event.target.value, inputCrypto, ouputCrypto);
        this.setState({result, amount: event.target.value});

    }

    conversorFunc(amount, inputCrypto, ouputCrypto){
        let result;
        if(ouputCrypto.name == 'USD'){
            result = numeral(inputCrypto.price_usd*parseInt(amount)).format('0,0.00');
        }else{
            result = numeral((inputCrypto.price_usd/ouputCrypto.price_usd)*parseInt(amount)).format('0,0.00');
        }
        return result;
    }


    render(){
        return(
            <div className='container conversor-container'>
                {console.log(this.state.selectedCrypto)}
                <h4>Currency Converter</h4>
                <div className='input-container'>
                    <input onKeyUp={this.converterHandler.bind(this)} placeholder='Enter Amount To Convert' className='amount form-control' type="text"/>
                    <div className='selectComp-div'>
                        <Select
                            name="crypto-select"
                            value={this.state.selectedCrypto}
                            onBlurResetsInput={false}
                            onSelectResetsInput={false}
                            clearable={false}
                            onChange={this.updateValue.bind(this)}
                            searchable={true}
                            options={this.props.cryptos}
                            labelKey='name'
                            valueKey='name'
                        />
                    </div>
                    <span>to</span>
                    <div className='selectComp-div'>
                        <Select
                            name="crypto-select"
                            value={this.state.cryptoToConvert}
                            clearable={false}
                            onChange={this.updateValue2.bind(this)}
                            searchable={true}
                            options={this.props.cryptos}
                            labelKey='name'
                            valueKey='name'
                        />
                    </div>
                    <div className='result-div'>
                        {this.state.amount}{this.state.selectedCrypto.name}={this.state.result}{this.state.cryptoToConvert.name}
                    </div>
                </div>
            </div>
        );
    }
}

export default Conversor;

网络应用:https://crypto-waatch.herokuapp.com/

代码:https://github.com/jorgeduardos/CryptoPrices

【问题讨论】:

  • 看来您的问题来自react-select 模块。
  • @FortuneEkeruo react-select 的实现是新的,我使用的是普通的选择标签,它也不起作用

标签: javascript reactjs redux state react-props


【解决方案1】:

查看您在 github 中的代码,您应该在组件 Conversor 上实现 componentWillReceiveProps,或者在 single_crypto 的状态上添加一个属性(例如:isFetching),以便在获取结束后加载转换器,因为“获取”是异步的。

场景一示例:

// conversor
componentWillReceiveProps (nextProps) {
    this.setState({
      selectedCrypto: nextProps.crypto,
    });
}

场景二示例:

render () {
  // ...
  {this.state.isFetching && <Conversor cryptos={this.props.cryptos} crypto={this.props.singleCrypto}/>}
  // ...
}

【讨论】:

  • 使用 componentWillReceiveProps 解决了我的问题,非常感谢。那么 componentwillreceiveprops 和 componentwillmount 有什么区别呢?我对这两个生命周期有点困惑。
  • componentWillMount 是 react 生命周期的第一步,它只会执行一次。 componentWillReceiveProps 在组件的 props 上执行每个机会。
猜你喜欢
  • 2021-04-21
  • 2022-11-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-24
相关资源
最近更新 更多