Luiz
Luiz

Reputation: 2055

How can i use the value that is been returned by my reducer

i'm kind in trouble here, if anyone could help me will be awesome.

So, i'm making this application using react hooks and redux, i want to use the value that i'm storing in database to make some action, let's say console.log that json or just the id. The part of storing in database and all of that is ok, but i just can't figure out how to use this in react component after the return from dispatch(addReport(newReport)).

Sorry if it's a dumb question

My component NewReport.js

import React, { useEffect, useState } from 'react'
import { useSelector, useDispatch } from 'react-redux'
import { getEmployees } from '../../actions/employees'
import { getTypeContracts } from '../../actions/typeContract'
import { addReport } from '../../actions/reports'


export default function NewRegister() {
    const [newReportState, setNewReportState] = useState({
        employee: "",
        typeContract: "",
        initialDate: "",
        finalDate: ""
    })
    const [reportState, setReportState] = useState({
        id:"",
        employee: "",
        typeContract: "",
        initialDate: "",
        finalDate: ""
    })

    const dispatch = useDispatch()
    useEffect(() => {
        // get employees for select input
        dispatch(getEmployees())
        // get type of contracts for select input
        dispatch(getTypeContracts())
    }, [])
    const employees = useSelector(state => state.employees.employee)
    const typeContracts = useSelector(state => state.typeContracts.typeContract)
    const reports = useSelector(state => state.reports.report)

    // send values from the form to state
    const handleChange = e => {
        const { name, value } = e.target
        // for verification of the change of the state, aways console.log outside this function
        setNewReportState({
            ...newReportState,
            [name]: value
        })
    }


    // submit the form
    function sendReportToStorage(newReport){
        dispatch(addReport(newReport))
        // IT'S HERE THAT I WANT TO DO SOME ACTION
    }

    function handleSubmit(e) {
        e.preventDefault()
        // grab the values from the state
        const { employee, typeContract, initialDate, finalDate } = newReportState
        const newReport = { employee, typeContract, initialDate, finalDate }
        //console.log(newReport)
        // to do -> if the values in newReport != initial Report
        sendReportToStorage(newReport)
    }        
    return (
        <div className="content">
            <h1 className="title-page">New Report</h1>
            <form onSubmit={handleSubmit} >
                <div className="form-input">
                    <label>Employee</label>
                    <select id="employees" name="employee" onChange={handleChange}>
                        <option value="0"></option>
                        {employees.map(employee => (
                                <option value={employee.id} key={employee.id}>{employee.name} - {employee.function}</option>
                            ))}
                    </select>
                    <button className="add-button">+</button>
                </div>
                <div className="form-input">
                    <label>Type of contract</label>
                    <select id="typeContract" name="typeContract" onChange={handleChange}>
                        <option value="0"></option>
                        {typeContracts.map(typeContract => (
                            <option value={typeContract.id} key={typeContract.id}>{typeContract.description}</option>
                        ))}
                    </select>
                    <button className="add-button">+</button>
                </div>
                <div className="form-input">
                    <label>Initial date</label>
                    <input type="date" name="initialDate" onChange={handleChange} />
                </div>
                <div className="form-input">
                    <label>Final date</label>
                    <input type="date" name="finalDate" onChange={handleChange} />
                </div>
                <button className="submit-button">New Report</button>
            </form>
        </div>
    )
}

My Actions reports.js

import axios from 'axios'
import { GET_REPORTS, DELETE_REPORT, ADD_REPORT } from './types'


// GET REPORT
export function getReports() {
    return dispatch => {
        axios.get('/api/report/')
            .then(res => {
                dispatch({
                    type: GET_REPORTS,
                    payload: res.data
                })
                console.log(res.data)
            })
            .catch(
                err => dispatch(returnErrors(err.response.data, err.response.status))
            )
    }
}

// ADD REPORT
export const addReport = (report) => {
    return dispatch => {
        axios.post("api/report/", report)
            .then(res => {
                dispatch({
                    type: ADD_REPORT,
                    payload: res.data
                })
                console.log("added report")
                console.log(res.data)
            })
            .catch(err => console.log(err))
    }
}

My reports.js reducer -> i think it's here that should be return some value for react component

import { GET_REPORTS, DELETE_REPORT, ADD_REPORT } from '../actions/types.js'


const initialState = {
    report: []
}

export default function (state = initialState, action) {
    switch (action.type) {
        case GET_REPORTS:
            return {
                ...state,
                report: action.payload
            }
        case DELETE_REPORT:
            return {
                ...state,
                report: state.report.filter(report => report.id !== action.payload)
            }
        case ADD_REPORT:
            return {
                ...state,
                report: [...state.report, action.payload]
            }
        default:
            return state
    }
}

Upvotes: 2

Views: 1702

Answers (1)

Hagai Harari
Hagai Harari

Reputation: 2877

If I understand you correctly, you want to do something anytime a post added,

right now, if your addReport working, anytime it will add report const reports = useSelector(state => state.reports.report) will assign reports as current data from store. therefore,


useEffect(() => console.log(reports),[reports])

The thing is, that this effect will run at each time you modify reports, not just in case of adding.

So you can create a special flag that will check that indeed post added


 const { report, isReportAdded } = useSelector(state => state.reports)     
 useEffect(() => {
    if (isReportAdded) {
         console.log(report)
         dispatch(...) // create function to set isReportAdded to false
    }}
   ,[report, isReportAdded])






   const initialState = {
     report: [],
     isReportAdded: false
   }

   export default function (state = initialState, action) {
    switch (action.type) {
      case GET_REPORTS:
        return {
            ...state,
            report: action.payload
        }
       case DELETE_REPORT:
         return {
            ...state,
            report: state.report.filter(report => report.id !== action.payload)
        }
       case ADD_REPORT:
         return {
            ...state,
            report: [...state.report, action.payload],
            isReportAdded: true
        }
      default:
        return state
      }
     }

Upvotes: 2

Related Questions