Home > Blockchain >  Value from Redux store always returns undefined
Value from Redux store always returns undefined

Time:06-19

Trying to store user input from form into redux, however value accessed through useSelector is always undefined.

Slice component:

import { createSlice } from "@reduxjs/toolkit";

export const userSlice = createSlice({
  name: "userSettings",
  initialState: {
    interval: 15000,
  },
  reducers: {
    updateInterval: (state, action) => {
      state.interval = action.payload
    }
  },
});

export const { updateInterval } = userSlice.actions;
export const userRefreshInterval = (state) => state.userSettings;

export default userSlice.reducer;

Input form component:

import React, { useState } from 'react';
import { Button, Form, FormGroup, Label, Input } from 'reactstrap';
import { useSelector, useDispatch } from 'react-redux'
import {userRefreshInterval, updateInterval} from "./store/userSlice.js";

export default function UserSettingsForm() {
  const [refreshInterval, setInterval] = useState("");
  const dispatch = useDispatch();
  const interval = useSelector(userRefreshInterval);

  console.log(interval); // <--- always undefined

  const handleSubmit = (e) => {
    e.preventDefault();
    dispatch(updateInterval(refreshInterval));
  };

  const handleChangeInterval = (text) => {
    setInterval(text);
  };

  return (
    <Form onSubmit={handleSubmit} style={{margin: 10}} inline>
      <FormGroup className="mb-2 mr-sm-2 mb-sm-0">
        <Label for="refreshInterval" className="mr-sm-2">Refresh Interval:</Label>
        <Input type="text" name="refreshInterval" id="refreshInterval" placeholder="interval" onChange={(e) => handleChangeInterval(e.target.value)} />
      </FormGroup>
      <FormGroup className="mb-2 mr-sm-2 mb-sm-0">
        <Label for="roundDecimal" className="mr-sm-2">Round results to decimal: 
        </Label>
        <Input type="text" name="roundDecimal" id="roundDecimal" placeholder="roundDecimal" />
      </FormGroup>
      <Button>Submit</Button>
    </Form>
  );
}

Update with store.js as asked:

import { configureStore } from '@reduxjs/toolkit'
import userReducer from "./userSlice";

export default configureStore({
  reducer: {
    user: userReducer
  }
})

Feeling like missing something simple, pls help to identify the cause of the issue.

CodePudding user response:

I haven't seen your store first.

try this

export const userRefreshInterval = (state) => state.user;

Because you have named your slicer as user. If you want to get state using

export const userRefreshInterval = (state) => state.userSettings;

Configure your store like the bellow

export default configureStore({
  reducer: {
    userSettings: userReducer
  }
})

CodePudding user response:

// your component
import React, { useState } from "react";
import { Button, Form, FormGroup, Label, Input } from "reactstrap";
import { useSelector, useDispatch } from "react-redux";
import {  updateInterval } from "./store/userSlice.js";

export default function UserSettingsForm() {
  const [refreshInterval, setInterval] = useState("");
  const dispatch = useDispatch();
  // need to change here, no need of userRefreshInterval, no need to even export or create this function in reducer file
  const interval = useSelector((state) => state.user.interval);

  console.log(interval); // <--- always undefined

  const handleSubmit = (e) => {
    e.preventDefault();
    dispatch(updateInterval(refreshInterval));
  };

  const handleChangeInterval = (text) => {
    setInterval(text);
  };

  return (
    <Form onSubmit={handleSubmit} style={{ margin: 10 }} inline>
      <FormGroup className="mb-2 mr-sm-2 mb-sm-0">
        <Label for="refreshInterval" className="mr-sm-2">
          Refresh Interval:
        </Label>
        <Input
          type="text"
          name="refreshInterval"
          id="refreshInterval"
          placeholder="interval"
          onChange={(e) => handleChangeInterval(e.target.value)}
        />
      </FormGroup>
      <FormGroup className="mb-2 mr-sm-2 mb-sm-0">
        <Label for="roundDecimal" className="mr-sm-2">
          Round results to decimal:
        </Label>
        <Input
          type="text"
          name="roundDecimal"
          id="roundDecimal"
          placeholder="roundDecimal"
        />
      </FormGroup>
      <Button>Submit</Button>
    </Form>
  );
}

// your reducer file
import { createSlice } from "@reduxjs/toolkit";

export const userSlice = createSlice({
  name: "userSettings",
  initialState: {
    interval: 15000,
  },
  reducers: {
    updateInterval: (state, action) => {
      state.interval = action.payload;
    },
  },
});

export const { updateInterval } = userSlice.actions;
// removed userRefreshInterval function

export default userSlice.reducer;

Let me know if it works!

  • Related