如何在从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
属性?
答案 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