简体   繁体   中英

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

I have two components "parent" and "child". In the "parent" component I get an array of elements using "axios". The "child" component is a "modal" which has an input and a send button which adds an element to the array.

Getting items and adding them to the database works fine. The database I use is MongoDB and on the back end there is node and express.

How can I get the "parent" component to render when I add a new element with the "child" component? Currently when adding a new element using the "child" component the database updates but the "parent" component does not. The parent component updates when I refresh the page, then it renders the updated table from the database.

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))
}

Inwould do it like so: notify a parent when the data is updated and force the parent to re-render when it receives this notification:

Parent.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();
        });
    }
}

As you know, pre-rendering causes a state change or props.

In the "parent" component I added "update: false" to the state. I created the "myForceUpdate" function in which I change the "update: true" state Passes the "myFirceUpdate" function to the "child" component. In the "child" component I put "props" into "then".

When adding an element to an array, the "myForceUpdate" function in the "parent" component starts and changes the state of the "parent" component, but it doesn't re-render.

What am I doing wrong?

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))

The solution to the above problem was obtained by using componentDidMount and 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))                                                
...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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