简体   繁体   中英

How to fetch data after action has been done in redux?

I want to perform an PUT request to my firebase db after some action has been called and performed. My global state has an array os objects called "items"; I have some actions in which I can update this array, like, adding objects, deleting or editing its properties. I do want to send a request right after adding, editing , or deleting them

My code:

import React, {Component} from 'react'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import {connect} from 'react-redux'
import axios from '../../axios'

import classes from './List.module.css'
import {Button,ListGroup} from 'reactstrap'
import Input from '../UI/Input/Input'
import Items from './Items/Items'


class List extends Component{

    componentWillMount() {
        axios.get('/list/items.json')
        .then(response=>{
           console.log("response.data")
           console.log(response.data)
           this.props.initialState(response.data)
        }).catch(error=>console.log(error))
      }

    render(){
        let inputElement = null
         if(this.props.input){
             inputElement=(
                <Input 
                changedName={this.props.changedName}
                changedDesc={this.props.changedDesc}
                addOrEdit={this.props.addItem}
                nameInput={this.props.state.nameInput}
                descInput={this.props.state.descInput}
                buttonText={this.props.state.buttonText}/>
             )
         } 

         let editElement = null
         if(this.props.state.edit){
            editElement=(
                <Input 
                changedName={this.props.changedName}
                changedDesc={this.props.changedDesc}
                addOrEdit={this.props.editItem}
                nameInput={this.props.state.nameInput}
                descInput={this.props.state.descInput}
                buttonText={this.props.state.buttonText}/>
             )
         }

         let itemElement = null

         if(this.props.items && this.props.items.length !== 0 ){
             itemElement = this.props.items.map((i,index)=>{
                 return <Items
                        className={classes.items}
                        id={index}
                        name={i.itemName}
                        key={index}
                        deleteClicked={()=>this.props.deleteItem(index)}
                        itemIndex={()=>this.props.itemIndexChanger(index)}
                        editInput={()=>this.props.editItemHandler(index)}
                        editIndex={this.props.state.editIndex}
                        editElement={editElement}/>
             })
         }else{
             itemElement = <h4 className={classes.items}>Please add an Item</h4>
         }

        return(
            <div className={classes.items}>
                <ListGroup> 
                    {itemElement}
                </ListGroup>
               <hr className={classes.hr}/>
                <Button 
                className={classes.button}
                onClick={this.props.toggleInputHandler} 
                size="sm"
                outline color='info'>
                    Add Items 
                    <FontAwesomeIcon icon='plus'/>
                </Button>
                {inputElement}
            </div>
        )
    }
}

const mapStateToProps = (state) =>{
    return{
        items:state.items,
        input:state.input,
        state:state,
    }
}

const mapDispatchToProps = dispatch=>{
    return{
        toggleInputHandler:()=>dispatch({type:'TOGGLE_INPUT_HANDLER'}),
        changedName:(event)=>dispatch({type:'CHANGED_NAME', payload:event.target.value}),
        changedDesc:(event)=>dispatch({type:'CHANGED_DESC',payload:event.target.value}),
        addItem:()=>{return(dispatch({type:'ADD_ITEM'}))},
        deleteItem:(index)=>dispatch({type:'DELETE_ITEM',index:index}),
        editItemHandler:(index)=>dispatch({type:'EDIT_ITEM_HANDLER',index:index}),
        editItem:()=>dispatch({type:'EDIT_ITEM'}),
        itemIndexChanger:(index)=>dispatch({type:'CHANGE_ITEM_INDEX',index:index}),
        initialState:(value)=>dispatch({type:'SET_STATE',payload:value})
    };
}


export default connect(mapStateToProps, mapDispatchToProps)(List)

NEED HELP HERE : Suppose that I use the addItem dispatch to add objects to my "items" array, it means, it updates the items in the state. How can I do an axios.put request after the additem has been called and performed completely, so I can send the updated state.items to my firebase?

Thank you guys for the attention!

With pure React and Redux, this kind of stuff can be done with componentDidUpdate :

componentDidUpdate(prevProps, prevState) {
    if (prevProps.someValue !== this.props.someValue) {
        axios.put( /* ...some axios call to sync someValue */ )
    }
}

This is fine for simple one-off things, but this approach can start to get really gross if you have a ton of values you want to sync, or if you want to do it from different components, or you want to kick off complex asynchronous behaviour from an action.

These sorts of behaviours are known as side-effects, and are the purpose of middleware libraries such as redux-thunk and redux-saga , which each have their own strengths and weaknesses in this area.

If you foresee your application making heavy use of side-effects such as API updates or other complex asynchronous behaviour in response to actions, I strongly recommend familiarizing yourself with one of these libraries instead of going the componentDidUpdate route.

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