React JS&获取响应数据后,Axios Render

时间:2018-01-04 16:43:49

标签: reactjs axios

如何在从axios GET请求中获取数据后进行组件渲染? 我有以下组件:

class CardPool extends React.Component{
    constructor(props){
        super(props);

        this.state = {
            cardListBacklog: [],
        };
    }

    componentWillMount(){
        axios.get('/cards').then(function(response){
            this.setState({cardListBacklog: response.data});
        }.bind(this));
    }

    render(){

        return(
            <div class="row">
                <Section name="Construction of Component 1 with a huge ass name that wont really fit in the section">
                    <Column columnName="BACKLOG">
                        <CardList id="card-list-1" column="0" cardList={this.state.cardListBacklog}/>
                    </Column>
                </Section>
            </div>
        );
    }
}

class CardList extends React.Component{
    constructor(props){
        super(props);

        this.state = {
            cardList: [],
            laneID: this.props.column
        }
    }

    componentWillMount(){
        this.setState({
            cardList: this.props.cardList,
        });
    }
render(){
        const {connectDropTarget} = this.props;

        return connectDropTarget(
            <div class={"card-list " + this.addClass()} id={this.props.id}>
                {   
                    this.state.cardList ?
                        this.state.cardList.map((card) => {
                            return <Card key={card.id} state={card} laneID={this.state.laneID}/>
                        })
                        : null
                }
            </div>
        );
}

问题是传递给state的{​​{1}} cardListBacklog未更新,而CardList组件中的cardList未更新仍然是空的。我究竟做错了什么?可能是因为我使用CardList设置了state属性?

3 个答案:

答案 0 :(得分:2)

当通过CardPool来电回复时,您没有机会让axios组件重新呈现。

修改render组件的CardPool功能,如下所示:

return this.state.cardListBacklog.length
        ? <div class="row">
            <Section name="Construction of Component 1 with a huge ass name that wont really fit in the section">
                <Column columnName="BACKLOG">
                    <CardList id="card-list-1" column="0" cardList={this.state.cardListBacklog}/>
                </Column>
            </Section>
          </div>
        : null;

This demo演示了准系统实现

答案 1 :(得分:0)

componentWillMount生命周期函数只执行一次,因此,当axios请求后的父列表中的cardList可用时,子组件的componentWillMount已经执行了因此它的状态没有更新。设置可直接从props派生的状态也不是一个好主意,你应该从从Child调用的父代传递一个处理程序

class CardPool extends React.Component{
    constructor(props){
        super(props);

        this.state = {
            cardListBacklog: [],
        };
    }

    componentWillMount(){
        axios.get('/cards').then(function(response){
            this.setState({cardListBacklog: response.data});
        }.bind(this));
    }

    removeCard = (card) => {
        //do what you need to update cardListBacklog
     }

    render(){

        return(
            <div class="row">
                <Section name="Construction of Component 1 with a huge ass name that wont really fit in the section">
                    <Column columnName="BACKLOG">
                        <CardList id="card-list-1" column="0" cardList={this.state.cardListBacklog} removeCard={this.removeCard}/>
                    </Column>
                </Section>
            </div>
        );
    }
}

class CardList extends React.Component{
    constructor(props){
        super(props);

        this.state = {
            cardList: [],
            laneID: this.props.column
        }
    }

    render(){
        const {connectDropTarget} = this.props;

        return connectDropTarget(
            <div class={"card-list " + this.addClass()} id={this.props.id}>
                {   
                        this.props.cardList.map((card) => {
                            return <Card key={card.id} state={card} removeCard={() => this.props.removeCard(card)} laneID={this.state.laneID}/>
                        })
                        : null
                }
            </div>
        );
}

答案 2 :(得分:0)

在axios请求后,我能够将数据从父级传递给子级:

父组件

export default class App extends React.Component {
constructor(props) {
    super(props);

    this.state = {
        peoples: []
    };
}

componentDidMount() {
    axios.get(`https://swapi.co/api/people`).then(res => {
        const peoples = res.data.results;
        this.setState({ peoples });
    });
}
render() {
    const { peoples } = this.state;
    return (
        <div>
            <Header />
            <Main peoples={peoples} />
            <Footer />
        </div>
    );
}

子组件

export default class Main extends React.Component {
constructor(props) {
    super(props);
    this.state = {
        peoples: []
    };
}
componentDidUpdate(prevProps) {
    const { peoples } = this.props;

    if (peoples !== prevProps.peoples) {
        this.setState({ peoples });
    }
}

render() {
    const { peoples } = this.state;
    return (
        <div>
            {peoples
                ? peoples.map(people => {
                      return <div>people.name</div>;
                  })
                : null}
        </div>
    );
}

问题是axios请求是异步的,并且仅在安装了子组件之后才有可能接收数据。因此,我们需要检查是否已使用react hook组件componentDidUpdate接收到响应,并将第一个值与接收到的新值进行比较,以使渲染正确打印。

https://reactjs.org/docs/react-component.html#componentdidupdate