Render child component after data add to state

Viewed 43

I'm new to the React and I'm working on a React Redux application. When I add a new item to the state I want to render the child component which shows item list. Currently item list showing in the state and new item also adding to that list (mobileList). How can I render child component when new item added to the state? Currently child component shows nothing.

Parent component

import React, { useEffect, useState ,ComponentState} from "react";
import { useSelector, useDispatch } from "react-redux";
import { Button, Container, Row, Col, Form } from "react-bootstrap";
import uuid from "react-uuid";
import allActions from '../Actions/index'
import MobileList from './MobileList';

const MobileCreation = () => {
  const dispatch = useDispatch();

  const initialMobileState = {
    id: "",
    modelName: "",
    brand: "",
    year: "",
    price: "",
  };

  const [mobile, setMobile] = useState(initialMobileState);
  const [submitted, setSubmitted] = useState(false);
  const [submitSuccesful, setSubmitSuccesful] = useState(false);

  const handleInputChange = (event) => {
    const { name, value } = event.target;
    setMobile({ ...mobile, [name]: value });
  };

  const saveMobile = (event) => {
    event.preventDefault();
    setSubmitted(true);

    if (mobile.modelName && mobile.brand && mobile.year && mobile.price) {
      var data = {
        Id: uuid(),
        ModelName: mobile.modelName,
        Brand: mobile.brand,
        Year: mobile.year,
        Price: mobile.price,
      };
    }

   dispatch(allActions.MobileActions.save(data));
   setSubmitted(false);
   setMobile(initialMobileState);
  };

  return (
      <>
    <Form onSubmit={saveMobile}>
      <Form.Group controlId="mobile.ModelName">
        <Form.Label>Model Name</Form.Label>
        <Form.Control
          type="text"
          placeholder="Enter model name"
          name="modelName"
          value={mobile.modelName}
          onChange={handleInputChange}
        />
        {submitted && !mobile.modelName && <div>Model name is required</div>}
      </Form.Group>
      <Form.Group controlId="mobile.Brand">
        <Form.Label>Brand Name</Form.Label>
        <Form.Control
          type="text"
          placeholder="Enter Brand name"
          name="brand"
          value={mobile.brand}
          onChange={handleInputChange}
        />
        {submitted && !mobile.brand && <div>Brand name is required</div>}
      </Form.Group>
      <Form.Group controlId="mobile.Year">
        <Form.Label>Year</Form.Label>
        <Form.Control
          type="text"
          placeholder="Enter year"
          name="year"
          value={mobile.year}
          onChange={handleInputChange}
        />
        {submitted && !mobile.year && <div>Year is required</div>}
      </Form.Group>
      <Form.Group controlId="mobile.Price">
        <Form.Label>Price</Form.Label>
        <Form.Control
          type="text"
          placeholder="Enter price"
          name="price"
          value={mobile.price}
          onChange={handleInputChange}
        />
        {submitted && !mobile.price && <div>Price is required</div>}
      </Form.Group>
      <Button variant="primary" type="submit">
        Submit
      </Button>
    </Form>
    <MobileList/>
    </>
  );
};

export default MobileCreation;

Child Component

import React, { useEffect } from "react";
import { useSelector, useDispatch ,} from "react-redux";
import Table from 'react-bootstrap/Table'

const MobileList = () => {
  const mobileList = useSelector((state) => state.mobileList);

  return (
    <>
      <Table striped bordered hover size="sm">
        <thead>
          <tr>
            <th>Model Name</th>
            <th>Brand Name</th>
            <th>Year</th>
            <th>Price</th>
          </tr>
        </thead>
        <tbody>{mobileList ? 
             mobileList.map(function(item, i){
            <tr>
                <td>item.ModelName</td>
                <td>item.Brand</td>
                <td>item.Year</td>
                <td>item.Price</td>
            </tr>
            }) :
           <tr>
               <td>No data</td>
           </tr>
        
            }
        </tbody>
      </Table>
    </>
  );
};

export default MobileList;

Reducer

const initialMobileListState = {
    mobileList:[]
}


const mobileReducer= (state = initialMobileListState, action) => {
    switch(action.type){
        case "SAVE":
            return {
                ...state,
                mobileList:[...state.mobileList, action.mobile]
            }
        case "FAIL":
            return state 
        default: 
            return state
    }
}

export default mobileReducer

enter image description here

1 Answers

The problem is in the wrong value in a selector. You needed to use

state.MobileReducer.mobileList

instead of

state.mobileList
Related