Home > other >  Prop sharing between components
Prop sharing between components

Time:05-16

I know, this topic has been handeled a lot, but I am still lost in my particular example. I have a react-select component, which is a part of another component, which is a part of App component.

SubjectSelect.tsx

export default function SubjectSelect({handleChange, value}) {
  
  return (
    <>
      <Select
          placeholder="Choose subject"
          value={value} // set selected value
          onChange={handleChange} // assign onChange function
      />
      <div><b>Your choice: </b> {value} </div>
    </>
  )
}

FormStepOne.tsx

import SubjectSelect from "../components/SubjectSelect";

export const SubjectSelector = ({value, handleChange}) => {
    
    return (
        <>
        <h1 className="text-3xl font-bold underline">
            Hi there! Please select book subject
        </h1>
            <SubjectSelect value={value} onChange={handleChange}/>
        </>
    );
}

And App.tsx

import React, { useState } from 'react'
import  { SubjectSelector } from '../formSteps/stepOne'
import  { ShowcaseBooks } from '../formSteps/stepTwo'

const options = [
  { value: 'fiction', label: 'Fiction' },
  { value: 'science', label: 'Science' },
]

export default function App() {
  const [books, setBooks] = useState('')
  const [selectedValue, setSelectedValue] = useState('');
  const handleChange = e => {
    setSelectedValue(e.value);
    alert('huhu')
  }
  const value = options.find(obj => obj.value === selectedValue)
  return (
    <div className="bg-blue-200">
      <div className="container mx-auto py-36 bg-blue-200">
        <div className="mt-12 px-96">
          <SubjectSelector 
            options={options}
            value={value}
            onChange={handleChange}/>
          <ShowcaseBooks books={books}/>
      </div>
    </div>
  </div>
  )
}

Somehow I am not passing the props right, so that my components showcase several errors. App.tsx complains about options and onChange, but I am lost and don't reallyfully undertand what is wrong and how to pass props corretly, so my App.js and therefore Showcase books "know" the selectdValue.

CodePudding user response:

The problem is you pass the handleChange function to SubjectSelector on the onChange prop, while that component is expecting it on a prop named handleChange.

In App.tsx you need something like this

  <SubjectSelector 
    options={options}
    value={value}
    handleChange={handleChange}/> // This is the fix

Because when you do this

export const SubjectSelector = ({value, handleChange}) => 

You're telling the component the name of the props to expect. You need to change your Subject selector in a similar manner.

CodePudding user response:

For first loading, the prop value you send is empty (because change event is not triggered). so It will turn your app into error.

So you need to check it not empty before parse it to HTML

SubjectSelect.tsx

export default function SubjectSelect({ options, handleChange, selectedVal }) {
  return (
    <>
      <select
        value={selectedVal && selectedVal.value} // set selected value
        onChange={handleChange} // assign onChange function
      >
        <option>Choose subject</option>
        {options.map((item: any) => {
          return (
            <option key={item.value} value={item.value}>
              {item.label}
            </option>
          );
        })}
      </select>
      <div>
        <b>Your choice: </b> {selectedVal && selectedVal.value}
      </div>
    </>
  );
}

FormStepOne.tsx

import SubjectSelect from "./SubjectSelect";

const SubjectSelector = ({ selectedVal, handleChange, options }) => {
  return (
    <>
      <h1 className="text-3xl font-bold underline">
        Hi there! Please select book subject
      </h1>
      <SubjectSelect
        options={options}
        selectedVal={selectedVal}
        handleChange={handleChange}
      />
    </>
  );
};

export default SubjectSelector;

And do not use value as variable name or prop to avoid conflict with key of object. Getting value from change event should be e.target.value

import React, { useState } from "react";
import SubjectSelector from "./SubjectSelect";

const options = [
  { value: "fiction", label: "Fiction" },
  { value: "science", label: "Science" }
];

export default function App() {
  const [selectedValue, setSelectedValue] = useState('');
  const handleChange = (e: any) => {
    setSelectedValue(e.target.value);
    alert(e.target.value);
  };
  const selectVal = options.filter((obj) => obj.value === selectedValue)[0];

  return (
    <div className="bg-blue-200">
      <div className="container mx-auto py-36 bg-blue-200">
        <div className="mt-12 px-96">
          <SubjectSelector
            options={options}
            selectedVal={selectVal}
            handleChange={handleChange}
          />
        </div>
      </div>
    </div>
  );
}

You can check my complete answer here. I hope it might helps you

https://codesandbox.io/s/delicate-smoke-n0eyjc?file=/src/App.tsx:0-804

  • Related