繁体   English   中英

子组件向数据库添加元素时如何重新渲染父组件?

[英]How to re-render the parent component when the child component adds an element to the database?

我有两个组件“父”和“子”。 在“父”组件中,我使用“axios”获得了一个元素数组。 “子”组件是一个“模态”,它有一个输入和一个向数组添加元素的发送按钮。

获取项目并将它们添加到数据库中工作正常。 我使用的数据库是MongoDB,后端有node和express。

当我使用“子”组件添加新元素时,如何让“父”组件呈现? 目前,当使用“子”组件添加新元素时,数据库会更新,但“父”组件不会。 当我刷新页面时,父组件会更新,然后它会从数据库中呈现更新的表。

Component Parent (main fragment):

class ShoppingList extends Component {
constructor(props){
    super(props)
    this.state = {
        items: []
    }
}

componentDidMount(){
    this.getPosts();
}

getPosts(){
    axios.get('/api/items')
        .then(res=>{const arrayItems = res.data;this.setState({items: arrayItems})})
        .catch(err=>console.log(err))
}

会这样做:在数据更新时通知父级,并在收到此通知时强制父级重新渲染:

父.js

class ShoppingList extends Component {
constructor(props){
    super(props)
    this.state = {
        items: []
    }
}

componentDidMount(){
    this.getPosts();
}

getPosts(){
    axios.get('/api/items')
        .then(res=>{const arrayItems = res.data;this.setState({items: arrayItems})})
        .catch(err=>console.log(err))
}

return (
        <Child notifyParent={() => this.forceUpdate()} />
);
}

Child.js

class Child extends Component {
    updatePost() {
        axios.post('...', something)
        .then(resp => {
            //...
            this.props.notifyParent();
        });
    }
}

如您所知,预渲染会导致 state 更改或道具。

在“父”组件中,我向 state 添加了“update: false”。 我创建了“myForceUpdate”function,其中我更改了“update: true”state 将“myFirceUpdate”function 传递给“child”组件。 在“child”组件中,我将“props”放入“then”。

向数组添加元素时,“父”组件中的“myForceUpdate”function 启动并更改“父”组件的 state,但不会重新渲染。

我究竟做错了什么?

Parent:                                                                           
class ShoppingList extends Component {
 constructor(props){
    super(props)
    this.state = {
        items: [],
        update: false
    }
}

componentDidMount(){
    this.getPosts();
    this.setState({
        update: true
    })
    console.log('CDM')
}

getPosts(){
    axios.get('/api/items')
        .then(res=>{const arrayItems = res.data;this.setState({items: arrayItems})})
        .catch(err=>console.log(err))
}

onDeleteClick = (id) => {
    axios.delete(`/api/items/${id}`)
        .then(()=>{this.setState({items: this.state.items.filter(item=>item._id!==id)})})
        .catch(err=>console.log(err)) 
}

myForceUpdate = () => {
    console.log('myForceUpdate')
    this.setState({
        update: true
    })
    console.log(this.state.update)
}

render(){
    return(
        <Container>
            <ItemModal addPost={this.myForceUpdate}/>

Child:
axios.post('/api/items',newItem)
       .then(res=>console.log(res.data))
       .then(()=>this.props.addPost())
       .catch(err=>console.log(err))

通过使用componentDidMount和componentDidUpdate得到了上述问题的解决方案。

Parent:
...
constructor(props){
        super(props)
        this.state = {
            items: [],
            update: false
        }
    }

    componentDidMount(){
        this.getPosts();
    }

    componentDidUpdate(){
       if(this.state.update === true){
            this.getPosts();
            this.setState({
                update: false
            })
        }
    }
...
myForceUpdate = () => {
        this.setState({
            update: true
        })
    }

    render(){
        return(
            <Container>
                <ItemModal addPost={this.myForceUpdate}/>
...

Child:
...
axios.post('/api/items',newItem)
       .then(()=>this.props.addPost())
       .catch(err=>console.log(err))                                                
...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM