Redux does not send to the store 2 properties at a time

Viewed 107

I'm new to Redux. I have a reducer with an initial state with 2 properties.

From a component I send data to store, but only one of the properties is delivered - either time or date. But I need to send both.

I tried to do async/await thinking that the interpreter simply runs out of time - even though it is not as much logical, I tried. It did not help me. Also I thought that Redux cannot accept objects but I researched and saw that it can. Then I proved to myself that it really can - I just simply sent only 1 property.

Code snippets are below.

*Reducer: *

const initialState = {
  date: {},
  time: {}
}

const dateTimeReducer = (state = initialState, action) => {
    switch (action.type) {
        case 'setDate':
            return {
                date: action.payload,
            }

        case 'setPickedCell':
            return {
                time: action.payload,
            }

        default:
            return state
    }
}
export default dateTimeReducer

*index.js*

import React from 'react'
import ReactDOM from 'react-dom'
import './css/style.comp.css'
import App from './App'
import { BrowserRouter } from 'react-router-dom'
import store from './redux/store'
import { Provider } from 'react-redux'
// import rootReducer from './redux/rootReducer'

// const store = createStore(rootReducer)

ReactDOM.render(
    <Provider store={store}>
        <BrowserRouter>
            <App />
        </BrowserRouter>
    </Provider>,

    document.getElementById('root')
)

*store.js*

import { createStore } from 'redux'
import rootReducer from './rootReducer'

const store = createStore(rootReducer)

export default store

*rootReducer.js*

import { combineReducers } from 'redux'
import dateTime from './reducers/dateTime'

export default combineReducers({ dateTime })

*Component - I will simplify, with a condition that I have no syntax mistakes and the code works when I send only 1 of 2 properties to a Redux store*

import Date from ''
import Time from ''

class Comp extends React.Component {
  state = {
     date: {...}, 
     time: {...} // both date and time already set during rendering cycle - through a function 
                 // acceptStateFromDate and acceptStateFromTime
  }

  acceptStateFromDate() {
    this.setState({ date: stateData })
  } 

  // same about acceptStateFromTime - those functions are used to get state data from a child component and are called while componentDidMount

  acceptStateFromTime() {
    ...
  }

  onConfirmClick = () => {
    this.props.isAllowedHandler()
    this.props.onDateSet(this.state.datePicker)
    this.props.onCellSet(this.state.timePicker)
  }

  componentDidMount() {
    acceptStateFromDate() 
    acceptStateFromTime()
  } 

  render() {
    return (
      <div> 
        <div onClick={this.onConfirmClick}> Confirm </div>
        <Time sendState={acceptStateFromTime} />
        <Date sendState={acceptStateFromDate} />
    )
  }
}

function mapStateToProps(state) {
    return {
        date: state.dateTime.date,
        time: state.dateTime.time,
    }
}

function mapDispatchToProps(dispatch) {
    return {
        onDateSet: (val) => dispatch({ type: 'setDate', payload: val }),
        onCellSet: (val) => dispatch({ type: 'setPickedCell', payload: val }),
    }
}

export default connect(mapStateToProps, mapDispatchToProps)(withRouter(Appointment))

All exports and imports are present in my code.

So, if I send through onConfirmClick only this.props.onDateSet({someObj})```, I will get in my Redux state date: {someObj}. Same about time - I will get time: {someObj}````.

But if I call those 2 props together, only one will be delivered to the store.

I guess the problem is deeper than the logic, probably I'm not so good enough either in React system or Redux.

Does anyone know where is the problem?

Thanks in advance!

1 Answers

Your reducers are wrong you have to return the state too. At the moment you are completely rewriting it:

return {
  date: action.payload,
}

Change your return statement to the following:

return {
  ...state,
  date: action.payload,
}

const dateTimeReducer = (state = initialState, action) => {
  switch (action.type) {
    case 'setDate':
      return {
        ...state,
        date: action.payload,
      }
    case 'setPickedCell':
      return {
        ...state,
        time: action.payload,
      }
    default:
      return state
  }
}
Related