React无法在componentWillMount()

时间:2017-05-11 07:34:29

标签: reactjs

我是新手做出反应。我正在尝试动态地使用_fetchUsers()从远程服务器获取数据。单击不同的导航选项卡时应更改状态apiUrl,尽管此处未显示。问题,我发现,$.ajax函数之前的日志显示空字符串this.state.apiurl。如果我在ajax的url属性上对url进行硬编码,则ajax可以返回正确的响应。有人可以解释为什么我没有为apiurl设置state,是与componentWillMount()相关的原因

export default class RegiteredUserTable extends Component {
    constructor() {
        super();
        this.state = {
            registeredUsers:[],
            tableProperties:[],
            apiUrl:''
        }
    }
    _fetchUsers() {
        console.log("this.props", this.props);
        if(this.props.match.params.tableId === "buyer-table"){
            this.setState({apiUrl:'/buyers/list-buyers'});
        } else if (this.props.match.params.tableId === "seller-table") {
            this.setState({apiUrl:'/sellers/list-sellers/'});
        }
        console.log('this.state.apiUrl',this.state.apiUrl);    
        $.ajax({
            method: 'GET',
            url: `${this.state.apiUrl}`,
            success: (res) => {
                console.log('res',res);
                let registeredUsers = res.data;
                this.setState({registeredUsers});
            }
        });
    }

    _getTableProperty() {
        //property array
        console.log('this.state.registeredUsers',this.state.registeredUsers);
        const tableProperties = this.state.registeredUsers[0].keys;
        this.setState({tableProperties});
        return tableProperties.map(tableProperty => {
            return  (
                        <th>{tableProperty}</th>
                    )
        })
    }

    _getUsers() {
        return this.state.registeredUsers.map(registeredUser => {
                return (
                    <tr>
                        <td>{registeredUser.id}</td>
                        <td>{registeredUser.first_name}</td>
                        <td>{registeredUser.last_name}</td>
                    </tr>
                );
            }
        )
    }
    componentWillMount() {
        this._fetchUsers();
    }
    render() {
        return(
            <div className="container">
                <div className="row">
                    <div className="col-xs-12">
                    <div className="table-responsive">
                        <table className="table table-bordered table-hover">
                        <caption className="text-center">Agents' data</caption>
                        <thead>
                            <tr>
                                {this._getTableProperty()}
                            </tr>
                        </thead>
                        <tbody>
                            {this._getUsers()}
                        </tbody>
                        <tfoot>
                            <tr>
                            <td colSpan="5" className="text-center">Data retrieved from <a href="http://www.infoplease.com/ipa/A0855611.html" target="_blank">infoplease</a> and <a href="http://www.worldometers.info/world-population/population-by-country/" target="_blank">worldometers</a>.</td>
                            </tr>
                        </tfoot>
                        </table>
                    </div>
                    </div>
                </div>
            </div>

        );
    }
}

1 个答案:

答案 0 :(得分:0)

SetState是异步的,所以api调用一旦setStatestate变量中设置apiUrl,使用回调方法并在其中执行api调用。

像这样写_fetchUsers

_fetchUsers() {
    let tableId = this.props.match.params.tableId;

    this.setState({
        apiUrl: tableId === "buyer-table" ? '/buyers/list-buyers' : '/sellers/list-sellers/'
    }, () => {
         $.ajax({
            method: 'GET',
            url: `${this.state.apiUrl}`,
            success: (res) => {
                console.log('res',res);
                let registeredUsers = res.data;
                this.setState({registeredUsers});
            }
        });
    });       
}

或者更好的方法是将apiUrl存储在变量中,并在收到回复后执行setState,这样您就不需要执行setState两次了首先需要依赖setState

像这样:

_fetchUsers() {
    let tableId = this.props.match.params.tableId;
    let url = tableId === "buyer-table" ? '/buyers/list-buyers' : '/sellers/list-sellers/';
    $.ajax({
        method: 'GET',
        url: url,
        success: (res) => {
            console.log('res',res);
            let registeredUsers = res.data;
            this.setState({registeredUsers, apiUrl: url});
        }
    });       
}