React pass props between sibling components with hooks - reactjs

I'm new to React and creating small app with REST Api to get some practice! So, when I clicking to pokeBox, in sider must be displaying details information about selected pokemon.
I attaching screenshot , how it looks now.
But I have no idea how I have to get constant with Pokemon.url.
It's my structure:
Wrapper (Parrent Component);
1.1. PokemonsList (Children);
1.1.1 GridCards (Children of PokemonsList)
1.2. About (Children)
So, I must get pokemon.url from GridCards and how I understanding, save in parrent component.
But, how is it was with functional component?

Using the hooks you can set a state in the parent component:
const [selectedPokemon, setSelectedPokemon] = useState()
and trigger a function when a new pokeBox is clicked in which to call setSelectedPokemon(pokemon.url).
In this way, you just have to pass selectedPokemon to the child component About in which you can render what you want based on the selectedPokemon value.

I suggest you put a piece of state in the parent component that you can pass to the about component (here you will save the data of the pokemon you want to display). Then you make a function to set data to the state you've just created and pass it to the PokemonList component so you can call that function when you click the name of the pokemon.
In wrapper:
this.state = {
selectedPokemon: {} // Pass this state to about comp as props
}
// Pass this function to pokemonList comp as props
setPokemon = (pokemon) => this.setState({ selectedPokemon: pokemon });

Related

How to call functions in same level components in reactjs?

My root Component is App.js. It has many child components. But i have declare functions in child component and i need to access those function in equal level component in react js. [enter image description here][1]
this are the components hierarchy. i need to pass function from custom player to playbutton component
[1]: https://i.stack.imgur.com/XpEt1.png
Handle the state of the game in App.js. In their (custom player and playbutton component) parent. Pass the state function to them as props and handle the state there.
Ex:
Function App () {
const [SomeState, setSomeState] = setState()
Return
<>
<Button setSomeState={setSomeState}><\Button>
<Button2 setSomeState={setSomeState}><\Button2>
<\>
}
Those buttons handle the same state.
visit this site: https://www.pluralsight.com/guides/how-to-reference-a-function-in-another-component
You can pass state values to a child component as a prop, but you can also pass functions directly to the child component like this:
<ChildComponent
// The child component will access using actionName
actionName={this.actual_action_name}
/>
actionName is the name of the props that can be accessed by the child component. Once you trigger an action or pass the data from the child component, the same action's name will be accessed using this.props.action_name.
Let’s look at a simple example of passing the action to the child component.
<MyChildComponent
onSubmitData={this.onSubmitData}
/>

Updating parent component without a call back function in react js

I was doing a POC coding on React js with component which has a Child component.As far as I know, there was no other way to update the state of parent from child except through a call back function from the child to the parent component. In my case, I tried to pass the state of the parent to the child and set them on the child state directly as props (this.props.).I noticed that if I change the state of the child, the state of the parent is also getting updated. I'm bit confused. Could somebody please help ?
Here is my code.
index.js
ReactDOM.render(<App2/>,document.getElementById('root'));
App2.js - Parent component
import React from 'react'
import ScreenTest From './ScreenTest'
class App2 extends React.Component{
state={
address : {
houseName:'1234 House Name'
}
}
render(){
return(
<ScreenTest parentState={this.state} address={this.state.address} />
)
}
}
ScreenTest.jsx - Child Component
import React from 'react';
class ScreenTest extends React.Component{
state={
parentState: this.props.parentState,
address : this.props.address
}
clickButton = () =>{
let addressTemp = this.state.address;
addressTemp.city= "Kerala";
this.setState({
address:addressTemp
})
}
render(){
console.log("To view the state when the screen renders",this.state)
return(
<a onClick={this.clickButton}>Click me to update the state and re render </a>
)
}
}
Code explanation:
I am invoking App2 component which has a child Component ScreenTest. I pass the currentState of App2 to ScreenTest. In ScreenTest i set the state from the values passed as props. In ScreenTest I have an anchor tag when clicked, updates the "address" state of ScreenTest and re render Screen. When the screen is re rendered , i check the state to see that parentState is also getting updated with new Address (i.e city is added to it).
Please tell me how the parentState is also getting affected by it. I'm bit confused.
You must note that when docs say that in order to update parent state from child, you must make use of callback and let the parent update its state, its the ideal and the correct way of doing it
In your code you are accidently updating the parent state you mutate the state by calling
let addressTemp = this.state.address;
addressTemp.city= "Kerala";
In Javascript, object are used by reference and updating a property in object directly will update it for anyone using that reference
So when you assign props to state in constructor like below
state={
parentState: this.props.parentState,
address : this.props.address
}
The state properties hold the reference of props object and hence the props also get updated when you mutate the state property by updating addressTemp state
The ideal way to update state is to clone it and then make changes so that you avoid unexpected issues
clickButton = () =>{
let addressTemp = {...this.state.address}; // clone state
addressTemp.city= "Kerala";
this.setState({
address:addressTemp
})
}

Getting Component State

Lets say I have component named Vault
class Vault Component{
State : { animal: dog,color:blue}
}
Lets say I have button in component named App with a button
class App Component{
State: { animal:null,color:null}
}
<div onCLick = {goGetVaultData()} className="button">Press Me</div>
Question is how does goGetVaultData function look to extract state from a diffrent component
goGetVaultData(){
// what do I look like ?
}
If you want data from a parent component, have the parent pass it down as a prop, then access it using this.props.
If you want data from a child component, pass a function as a prop to the child. The child calls that function, and when they do you call this.setState to save the value, and access it later using this.state
If you want data from a sibling component, move the state up to whatever component is the common ancestor of the two components. That common ancestor passes props down to both components.

Why parent Component can change Input.value with setState?Doesn`t input have it`s own state?

As we know,parent Component can not change child Component state,because state is independent and private! And the Official documents also said "In HTML, form elements such as <input>, <textarea>, and <select> typically maintain their own state and update it based on user input",then why we can use this.setState({value:this.value+1}) in parent Component to change ???I was confused about this!
class NameForm extends React.Component {
constructor(props) {
super(props);
this.state = {value: 100};
setTimeout(
() => {
this.setState({value:(this.state.value+1)});
},
1000
);
}
render() {
return (
<inpt value={this.state.value} />
//value will change from 100 to 101
//if here is a user-defined component,we must use
//componentWillReceiveProps(nextProps){this.setState({value:nextProps.value})}
// to update child component,but the DOM component doesn`t need!why??
//Does DOM component hasn`t it`s own state?
);
}
}
from the same page, you get the quote, react mentions that the form inputs are a Controlled Components, which means that the parent component of them can affect there state and it can know some information of their current state, as the onChange listener on the input, the parent component will know when the input is changed and what its new state for the value.
the opposite of this is the uncontrolled components which is a component that the parent may not know anything about its current state, as the image slider in a page, the page doesn't know what is the images that the slider renders, and it doesn't know which image is active now, until you add a handler like onImageChange, which will tell the page which image is the active now, and by that you turned it from uncontrolled component to a controlled component.
Recap:
the controlled component: a component that changes its own state, based on parent component props values, and can share some of its state information with the parent component by the callbacks that the parent passes to it as props.
the uncontrolled component: a component that doesn't change its own state, based on the props that passed to it from the parent, and doesn't share pieces of its state with the parent by the callbacks that the parent passes to it as props.
I hope that answered your question.

How do I pass state between pages using react navigation?

I'm trying to pass state from main page to a details page. The details page changes the parent state successfully by calling function (via props). However, a re-render is not triggered and the details page is not updated (despite it having updated props correctly). How can I pass state to a child page (details) such that it will trigger it to re-render?
It seems like a similar question is asked here
but I don't quite understand it. I'm not using redux as this is a small app.
//Navigator Setup
const AppNavigator = createStackNavigator({
Home: {
screen: Home}
Details: {
screen: Details}
);
//Home page:
this.props.navigation.navigate("Details", {
changeDetails: this.changeDetails
details: this.state.details})
}
//Details page
let details = props.navigation.getParam("details", "n/a");
let changeDetails = props.navigation.getParam("changeDetails", "n/a");
//change things
//render stuff
Passing the data with navigation.navigate won't trigger a re-render since it is passing a copy of the props. You will need to find an other way to send the props so that your component gets aware of the changes.
You can for example connect your component to your redux state (assuming you're using redux). If you are not using redux, you can send a refresh fucntion from your parent component navigate('Child', { refresh: refreshFunction } to the Child
You can then access this function in the child ( via something like this.props.navigation.state.params.refresh();or const refresh() = this.props.navigation.getParam('regresh') ) before the back action. This will trigger updating the parent state to update.
I hope this help you
You have pass the data in correct way but while extracting the data you went wrong
let details = props.navigation.getParam("details", "n/a");
just put this.props
like this
console.log(props.navigation.getParam.changeDetails);
console.log(props.navigation.getParam.details)
console.log is just for debugging purpose you can assign it to any variable And you will receive the data in object form or in json form.set this in constructor, render() or where you want to use this data
as document say:
this.props.navigation.navigate('YOUR TARGET NAME', {
itemId: 86,
otherParam: 'anything you want here',
});
here is the full example,good luck
edit :
in child component in componentDidUpdate() method you must check that if props are changed set new props to state,then component will be re-rendered with new state's:
componentDidUpdate(){
if ('YOUR DATA FROM PARENT' != 'PREVIOUS DATA FROM PARENT SAVED IN STATE'){
this.setState({yourState: 'YOUR DATA FROM PARENT'})
}

Resources