Pass input to React sibling - reactjs

I'm having trouble passing data between two React siblings. I need to have an input component that will receive and pass the input to sibling that will handle the input and perform some logic.
I get to receive the data in the parent, but I cannot seem to get the passing to the sibling to work...
This is the wrapper/parent
const [corpBrandId, setCorpBrandId] = useState("");
const [secondInput, setSecondInput] = useState("");
const handleCorpBrandIdChange = ({ target }) => {
setCorpBrandId(target.value);
};
const handleSecondInputChange = ({ target }) => {
setSecondInput(target.value);
};
const handleClick = () => {
// console.log(corpBrandId);
// console.log(secondInput);
};
return (
<div className="App">
<InputField
label="Corporate brand ID "
onChange={handleCorpBrandIdChange}
value={corpBrandId}
/>
<TableConnect corpBrandId={corpBrandId} secondInput={secondInput} />
<InputField
label="Second input param"
onChange={handleSecondInputChange}
value={secondInput}
/>
<button onClick={handleClick}>Click me</button>
</div>
);
}
export default MainWrapper;
And here's the input component:
return (
<div>
<label>{label}</label>
<input type="text" value={value} name={name} onChange={onChange} />
</div>
);
};
export default InputField;
I've got no working or remotely close code how to receive the data...
This doesn't work in the sibling:
return (
<div>
Test
{props.corpBrandId}
{props.secondInput}
</div>
);
}
Anyone got any idea?

Based on your comment to #Shahar's answer, it sounds like you maybe haven't defined props in your TableConnect component. It should look something like this:
const TableConnect = (props) => {
return (
<div>
Test
{props.corpBrandId}
{props.secondInput}
</div>
);
};
Here's a codesandbox where TableConnect is correctly receiving the input from your input fields: https://codesandbox.io/s/throbbing-cloud-wgub8?file=/src/App.js

export default InputField;
return (
<div>
Test
{props.corpBrandInput} //shouldnt it be: corpBrandId
{props.inputText} //shouldnt it be: secondInput
</div>
);
}

Related

Passing Data from Parent to Child Component's Input Field in ReactJS

I am working on a personal project in React for the first time. It has a structure of the following form (the following is simplified):
const Parent = () => {
const handleSubmit = (e) => {
e.preventDefault();
// Series of variables to hold the values from Child2
}
return (
<div>
<form onSubmit={handleSubmit}>
<div>
<Child1 name="child1"/>
<Child1 name="child2"/>
</div>
<button>Submit</button>
</form>
</div>
);
}
const Child1 = () => {
return (
<div>
<Child2 name="childchild1"/> // Child 2 components are individual inputs fields
<Child2 name="childchild2"/>
<Child2 name="childchild3"/>
</div>
);
}
const Child2 = () => {
return (
<div>
<input type="number" .......></input>
</div>
);
}
Basically put, I would like to add an import button in my Parent component which will fill the fields found in the Child2 Components. My question is: How would I go about passing the values from my Parent component to my Child2 Components so that they fill their input fields? I am looking for a relatively clean solution if possible. Thanks!
Component are build to be reusable. The clean way is to pass value from Child2 to Parent through Child 1.
const Parent = () => {
const [state1, setState1] = useState({})
const [state2, setState2] = useState({})
const handleSubmit = (e) => {
e.preventDefault();
// Series of variables to hold the values from Child2
}
return (
<div>
<form onSubmit={handleSubmit}>
<div>
<Child1 value={state1} onChange={setState1} name="child1"/>
<Child1 value={state2} onChange={setState2} name="child2"/>
</div>
<button>Submit</button>
</form>
</div>
);
}
const Child1 = ({ value, onChange }) => {
return (
<div>
<Child2 value={value.substate1} onChange={v=>onChange({...value, substate1: v})} name="childchild1"/> // Child 2 components are individual inputs fields
<Child2 value={value.substate2} onChange={v=>onChange({...value, substate2: v})} name="childchild2"/>
<Child2 value={value.substate3} onChange={v=>onChange({...value, substate3: v})} name="childchild3"/>
</div>
);
}
const Child2 = ({ value, onChange }) => {
return (
<div>
<input value={value} onChange={onChange} type="number" .......></input>
</div>
);
}
If that answer is unacceptable for you, you can have a look to redux or react context, but that breaks the reusability of the component and thats not "clean"

Passing field value from Child to Parent Component onChange with React

I am working on a project with React for the first time. What I am trying to do is send a Child component's value that is within an input field to a variable in its Parent. More precisely, I would like the value to be transmitted whenever the value in the input field is changed. Here is a basic overview of what I have (simplified):
const Parent = () => {
const handleSubmit = (e) => {
e.preventDefault();
// Series of variables to hold the values from Child2
}
return (
<div>
<form onSubmit={handleSubmit}>
<div>
<Child1 name="child1"/>
<Child1 name="child2"/>
</div>
<button>Submit</button>
</form>
</div>
);
}
const Child1 = () => {
return (
<div>
<Child2 name="childchild1"/>
<Child2 name="childchild2"/>
<Child2 name="childchild3"/>
</div>
);
}
const Child2 = () => {
return (
<div>
<input type="number" .......></input>
</div>
);
}
In brief, my goal is to have the values from the input fields in the component Child2 to be transmitted to some array of values in Parent. That being said, I have looked at multiple ways of lifting up values in React online, but I haven't found something similar to my scenario. What would be the best way of proceeding? Thanks!
I think you can use useContext feature from react. so it is basically a way to manage state globally and you can share state between deeply nested components. so I'm thinking to make a function on the Parent that can be used from nested child to get value, you can use onChange method for instance
import { createContext, useContext } from "react";
const UserContext = createContext();
const Parent = () => {
const handleSubmit = (e) => {
e.preventDefault();
// Series of variables to hold the values from Child2
};
const handleInput = (data) => {
console.log(`this is data ${data.target.value}`);
};
return (
<UserContext.Provider value={handleInput}>
<div>
<form onSubmit={handleSubmit}>
<div>
<Child1 name="child1" />
<Child1 name="child2" />
</div>
<button>Submit</button>
</form>
</div>
</UserContext.Provider>
);
};
const Child1 = () => {
return (
<div>
<Child2 name="childchild1" />
<Child2 name="childchild2" />
<Child2 name="childchild3" />
</div>
);
};
const Child2 = () => {
const handleInput = useContext(UserContext);
return (
<div>
<input type="number" onChange={(e) => handleInput(e)}></input>
</div>
);
};
export default Parent;
perhaps this link can help you useContext
you can send a function from parent to child 1 then to child2, in this case we gonna send this function handleGetDataFromParent={getDataFromParent}
const Parent = () => {
const handleSubmit = (e) => {
e.preventDefault();
// Series of variables to hold the values from Child2
}
const getDataFromParent=(data)=>{
console.log('DATA from Child2', data)
}
return (
<div>
<form onSubmit={handleSubmit}>
<div>
<Child1 name="child1" handleGetDataFromParent={getDataFromParent}/>
<Child1 name="child2" handleGetDataFromParent={getDataFromParent}/>
</div>
<button>Submit</button>
</form>
</div>
);
}
const Child1 = ({handleGetDataFromParent}) => {
return (
<div>
<Child2 name="childchild1" handleGetDataFromParent={handleGetDataFromParent}/>
<Child2 name="childchild2" handleGetDataFromParent={handleGetDataFromParent}/>
<Child2 name="childchild3" handleGetDataFromParent={handleGetDataFromParent}/>
</div>
);
}
const Child2 = ({handleGetDataFromParent}) => {
const setNumber=(number)=>{
handleGetDataFromParent(number)
}
return (
<div>
<input type="number" onChange={(n)=>setNumber(n)}.......></input>
</div>
);
}

Pass hook or function to a child component

What is the preferred way to change state in React using Hooks?
Option 1: I think this is the more "traditional"
function App() {
const [input, setInput] = useState('');
const onInputChange = (event) => {
setInput(event.target.value)
};
return (
<div className='App'>
<Form onInputChange={onInputChange} />
</div>
);
}
const Form = ({ onInputChange }) => {
return (
<div>
<div>
<div>
<input
type='text'
onChange={onInputChange}
/>
<button'>
Submit
</button>
</div>
</div>
</div>
);
};
export default Form;
Option 2: But I have seen people do this
function App() {
const [input, setInput] = useState('');
return (
<div className='App'>
<Form onInputChange={setInput} />
</div>
);
}
export default App;
const Form = ({ onInputChange }) => {
return (
<div>
<div>
<div>
<input
type='text'
onChange={(e) => {
onInputChange(e.target.value);
}}
/>
<button>
Submit
</button>
</div>
</div>
</div>
);
};
export default Form;
In Option 1 in the App component the logic to change it's state is there.
In Option 2, the logic to change App component is in a child component, right?
If I understand correctly, I think Option 1 makes more sense. What do you think?
option 1 is better because we only have to pass the props or data to child component not the logic , Logic must be reside in parent component.

How to set focus on child component's input on a button click in the parent in React Hooks

I have a parent component that has a button with an onClick event and when there is an error I want to focus on an input that is in a child component. I know this can be done using useRef but I keep getting an undefined error. Here is my code:
/* Parent Component */
const parent = () => {
const acresRef = useRef();
const addrRef = useRef();
const acresFocus = () => {
acresRef.current.focus();
};
const addressFocus = () => {
addrRef.current.focus();
};
return (
<Child addrRef={addrRef} acresRef={acresRef} />
<button onClick={acresFocus} />
<button onCLick={addressFocus} />
)
}
/*Child Component*/
const Child = forwardRef(
({props}, acresRef, addrRef) => (
<div>
<label for="address">Address</label>
<input type="text" name="address" ref={addrRef} />
</div>
<div>
<label for="acres">Acres</label>
<input type="text" name="acres" ref={acresRef} />
</div>
)
);
You are incorrectly using refs here. forwardRef works when ref is passed to the component. Anything apart from that is a prop to the component. So in your case, acresRef and addrRef will be received within props by the child component.
/*Child Component*/
const Child = (props) => (
<>
<div>
<label htmlFor="address">Address</label>
<input type="text" name="address" ref={props.addrRef} />
</div>
<div>
<label htmlFor="acres">Acres</label>
<input type="text" name="acres" ref={props.acresRef} />
</div>
</>
);
/* Parent Component */
const Parent = () => {
const acresRef = React.useRef();
const addrRef = React.useRef();
const acresFocus = () => {
acresRef.current.focus();
};
const addressFocus = () => {
addrRef.current.focus();
};
return (
<>
<Child addrRef={addrRef} acresRef={acresRef} />
<button onClick={acresFocus}>acres</button>
<button onClick={addressFocus}>address</button>
</>
);
};
Check this codesandbox here.
You may also just bind the props like so :
const Child = (props) => {
const onClick = props.onClick;
return(<div><p>
{onClick()}
</p>
</div>
);
}
/* Parent Component */
const ParentEl = () => {
const onClick = ()=>{return "hi"};
return (
<div>
<Child onClick={onClick} />
</div>
)
}
/*Child Component*/
export default function App() {
return (
<div className="App">
<ParentEl />
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
</div>
);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
or a codesandbox link to see directly what it does :
https://codesandbox.io/s/hidden-water-s8qjj?file=/src/App.js
here :
const onClick = props.onClick;
in the child component is doing all the magic

Form looses focus after single character input?

I created a form with a state attached to it , but after every character input the form looses focus.
i realize its because the state cause the form to re render how do i escape this?
import axios from 'axios'
const App = () => {
const [countries,setCountries] =useState([])
const [ newName,setnewName ] = useState('')
useEffect(()=>{
axios.get('https://restcountries.eu/rest/v2/all')
.then(response=>{
setCountries(response.data)
})
},[])
const handleChange = (event) =>{
setnewName(event.target.value)
}
const Finder = ()=>{
return(
<div>
<form>
<div>
Find country : <input value={newName} onChange={handleChange} />
</div>
</form>
</div>
)
}
return(
<div>
<p>Meow</p>
<Finder/>
</div>
)
}
export default App```
As you are rendering Finder as a component and it will be create a new function on each and every render instead as you are rendering it inside a component invoke it as a function like below
try changing the return statement as
return(
<div>
<p>Meow</p>
{Finder()}
</div>
)
Please go through this sandbox for reference

Resources