React, update chexkbox properly - javascript

Hi my problem is that i have parrent component which has a checkbox. This parrent component has many child components with chechboxes too. I need to do this:
If i click parrent checkbox i also need set state child checkbox. But i shoul be able t o unclick some child chcekboxes after that,
My child ocmponent liik like this:
export class ThemePartKnowledge extends Component {
static get propTypes() {
return {
knowledge: PropTypes.object.isRequired,
};
}
constructor(props) {
super(props);
this.state = {
isChecked:false,
}
}
render() {
return (
<Card className={'themePartKnowledge ml-2'}>
<Card.Header className={'d-flex flex-column flex-md-row p-x0'}>
<Form.Group controlId="formBasicCheckbox" className={'m-0 d-inline-block'}>
<Form.Check c type="checkbox" className={'my-auto'}/>
</Form.Group>
</Card.Header>
</Card>
);
}
}
My parrent controller is just sending isParrentChcecked props to this component.
How could I do this what i want? Thx for help
Edit:
So my structure look like this
Parrent
Child
Child
Child

componentDidUpdate does exactly that. Here whenever isParentChecked is changing, I am synchronising my isChecked state to parent.
componentDidUpdate(prevProps, prevState){
if(prevProps.isParentChecked !== this.props.isParentChecked){
this.setState({isChecked: this.props.isParentChecked})
}
}

Related

React: State won't change onClick and update component

I've got a parent component with a state to detect if the user has clicked it, and the parent component uses a child component which contains an item that I want to hide if the user has clicked the parent component.
Here is the parent component:
class Parent extends Component {
constructor (props) {
super(props);
this.state = {
clicked: false
};
}
setClick = () => {
this.setState({clicked: true});
};
render() {
// ...
return (
<div onClick={this.setClick}>
<Child isClicked={this.state.clicked} />
</div>
)
}
}
Here is the child component, inside my return:
return (
<div ...>
{!props.isClicked && ( ... then render the item ... )}
</div>
)
So when the user clicks on my parent component, I am trying to change the state of clicked, and then I'm passing clicked as a prop to my child component, and inside the child component an item is rendered depending on the state of clicked. Right now, if I click on the parent component, the state is not changing and the item is still being rendered when it isn't supposed to be. What is the problem?
You need to access the props in child with this.props.isclicked
So you're child component should look like this
class Child extends React.Component<{isClicked:boolean}>{
render(){
return (
<div>
{`I am ${this.props.isClicked ? `clicked` : `not clicked` }`}
</div>
)
}
}

Best way to recieve props from child to parent react component

I have an array which I want to save in my database. I have a page (parent component) and a form (child component) where my birthday input is (the one I'm saving in database). The select html elements are in the child component, and I take their values after every change. Now I need to pass recieved values from select elements back to my parent component and update the array with the recieved props. I will try to recreate my code as best as I can:
AuthenticationPage.js (Parent):
import React from 'react';
class AuthenticationPage extends Component {
constructor(props) {
super(props);
this.state({
setMonth:null
setDay:null
setYear:null
})
}
render() {
return(
<div>
<SignupForm // This is where I call my child component
onChange={(monthValue) => this.setState({ setMonth: monthValue })}
initialValues={{
dateofbirth: [
{
month: this.state.setMonth, // This one is okey but I can use onChange just to change one state
day: this.state.setDay,
year: this.state.setYear
}
]
}}
/>
</div>
)
}
}
export default AuthenticationPage;
SignupForm.js (Child):
import React from "react";
import SelectSearch from "react-select-search";
const SignupForm = (props) => (
<FinalForm
{...props}
render={(fieldRenderProps) => {
const {
// Here I render props from parent component
} = fieldRenderProps;
function monthPicker(monthValue) {
props.onChange(monthValue);
// How can I update the state of setDay and setYear states in parent component
}
return (
<Form className={classes} onSubmit={handleSubmit}>
<SelectSearch
options={month}
onChange={(monthValue) => monthPicker(monthValue)} // This is ok, I change setMonth state in parent with this function
/>
<SelectSearch
options={day}
// How to work with this, this is day input
/>
<SelectSearch
options={year}
// How to work with this, this is year input
/>
</Form>
);
}}
/>
);
export default SignupForm;
So basically I want to update states in parent component after onChange happens on select elements in my child component. I'm new to React and I can't figure this out whole day, so any help will mean a lot.
Child should receive a 'onChange' function prop. That will be called inside the child component, every time the values on the form are changed (this.props.onChange(newValue)).
The parent should hold a state of the values that will be updated accordingly (<SignupForm ... onChange={(newValue) => this.setState({ value: newValue })} />)
From parent to child you can pass data through props, but from child to parent best way is by function , i ll try to write an example below, i always code with functional component so my syntax won't be right below, but i hope you ll get the idea ...
Parent Component
class Parent extends React.Component {
constructor(props) {
super(props);
this.state({
monthValue:null
})
}
// this function send as a prop
const updateMonthValue =(value)=>{
this.state.monthValue=value
}
render() {
return <Child updateMonthValue={updateMonthValue} />;
}
}
Child Component
const Child =(props) => {
const submitHandler =(value) =>{
//here you can call the function of parent and the function in the parent will update state of parent
props.updateMonthValue(value)
}
render() {
return <h1><button onClick={()=>submitHandler("june")} /></h1>;
}
}

Can a Child component Access its Containing Component's Methods?

I have seen similar questions to this but they are usually talking about a parent accessing a child component's methods or passing in methods through props. My question is on a specific situation, using props.children, and having any child component be able to call a method on the parent that is rendering props.children.
A simplified example of what im trying to achieve:
class WrapperComponent extends React.Component {
constructor(props){
super(props);
this.handleInputChange = this.handleInputChange.bind(this)
}
handleInputChange(e){
console.log("neat, you changed the input")
}
render() {
return (
<form>
{this.props.children}
</form>
)
}
}
And the component that is calling said component and passing in the children as props.
const Component = (props) => {
return(
<WrapperComponent>
<div className="form-group" >
<label>
<div>Text</div>
<input onChange={this.handleInputChange} type={"text"}/>
</label>
</div>
</WrapperComponent>
)
}
The idea is that I can render a component that holds certain logic, and pass in the elements as children for that component to render, but also that the props.children can then call said logic within the wrapper, so I can pass in different children in different use cases, but the handling will always be the same. Is there a way to do this at all?
You can clone your elements and add new props to them using some built-in React goodies:
class WrapperComponent extends React.Component {
constructor(props){
super(props);
this.handleInputChange = this.handleInputChange.bind(this)
}
handleInputChange(e){
console.log("neat, you changed the input")
}
render() {
return (
<form>
{React.Children.map(
this.props.children,
el => React.cloneElement(el, {onInputChange: this.handleInputChange})
)}
</form>
)
}
}
Then (remove WrapperComponent):
const Component = (props) => {
return(
<div className="form-group" >
<label>
<div>Text</div>
<input onChange={props.onInputChange} type={"text"}/>
</label>
</div>
)
}
Then:
ReactDOM.render(
<WrapperComponent><Component /></WrapperComponent>,
document.getElementById('root')
)
Yes, there's a way, but its not straightforward, and you may want to consider a different approach.
In order for a child component to have access to the methods of an arbitrary parent, the parent must override the child's props. This can be done using React.cloneElement in the render() function of the parent. In your example:
class WrapperComponent extends React.Component {
constructor(props){
super(props);
this.handleInputChange = this.handleInputChange.bind(this)
}
handleInputChange(e){
console.log("neat, you changed the input")
}
render() {
return (
<form>
{React.Children.map(this.props.children, child => (
React.cloneElement(child, {handleInputChange: this.handleInputChange}
)}
</form>
)
}
}
Then, you can access the method in the child via this.props.handleInputChange.

How to get state of child component in react native

I have Main Component file and use in another child component.
I have to get state of the child component.
Ex :- Home (Parent)
- Form (Child) component i have been set the value of any text box in state. So ho can i get the state value of Form component into the main component.
Generally in React (and React-Native) information is passed down from the parent component to its children. However if you need to change something in the parent component's state based on the child-component's state, you can pass a function to the child that does just that.
For example:
// Inside Parent Component
openModalFromParent() {
this.setState({ modalOpened: true });
};
// Passing Function to Child
<ChildComponent openModal={ this.openModalFromParent } />
// Inside Child Component
<TouchableHighlight onPress={ () => this.props.openModal() } />
In this example the button in the child component would trigger a function that alters the state of the parent component - hope this helps!
Pass the function as a prop to the child component
//Parent Component
export default class Home extends Component {
constructor(props) {
super(props);
this.state = {
username: '',
password: '',
};
this._handleChange = this._handleChange.bind(this);
}
_handleChange(e) {
const { name, value } = e.target;
this.setState({
[name]: value
});
}
render(){
return(){
<Form valueChange={this._handleChange} />
}
}
}
//Child Component
export default class Form extends Component {
render(){
return(){
<div>
<input type="email" name="username" onChange={(e) => this.props.valueChange()} value={username}/>
<input type="password" name="password" onChange={(e) => this.props.valueChange()} value={password}/>
</div>
}
}
}
In React, your state can only flow down from the parent to the children.
What you should do is move the state from the child to the parent and then pass the state to the child as props.
Try reading this: https://reactjs.org/docs/lifting-state-up.html

ReactJS: How to get state property of another component?

There is a main component, which uses a menu component. The menu component is using a state property to save the information about selected menu item. But now I need to get the selected module in the main component. How do I do that?
class Main extends Component {
doSomething(module) {
console.log(module) // should get 'targetValue'
// I need to get the info, which module is selected.
// This info is stored as a state value in the `MainMenu` Component
// How do I get this information? I can't use the parameter `selectModule` as it is done here.
}
render() {
return (
<div>
<MainMenu />
<Button
onClick={ this.doSomething.bind(this, selectedModule) }
/>
</div>
)
}
}
In this component a menu is generated for each module (of modules array). By clicking on one item, this module is stored into module state variable.
class MainMenu extends Component {
constructor(props) {
super(props)
this.state = {
module: 'initialValue'
}
}
selectModule(module) {
this.setState({ module })
}
render() {
return (
<Menu>
<Menu.Item onClick={ this.selectModule.bind(this, 'targetValue') } >
{ title }
</Menu.Item>
</Menu>
)
}
}
Instead of doing some magic and examining internal state if children components lift the state to parent. Child becomes stateless.
class Main extends Component {
state = {
module: 'initialValue'
}
setActiveModule = (module) => {
this.setState({ module })
}
render() {
return (
<MainMenu onChange={this.setActiveModule} />
)
}
}
class MainMenu extends Component {
onClick = (module) => () => {
this.props.onChange(module)
}
render() {
return (
<Menu>
<Menu.Item onClick={this.onClick(title)} >
{title}
</Menu.Item>
</Menu>
)
}
}
Instead on maintaining the state in MainMenu component, maintain in parent component Main, and pass the module value in props, also pass a function to MainMenu to update the state of parent component Main from child MainMenu.
Write it like this:
class Main extends Component {
constructor(props) {
super(props)
this.state = {
module: 'initialValue'
}
this.update = this.update.bind(this);
}
update(value){
this.setState({
module: value
});
}
doSomething(){
console.log(this.state.module);
}
render() {
return (
<div>
<MainMenu module={this.state.module} update={this.update}/>
<Button
onClick={ this.doSomething.bind(this) }
/>
</div>
)
}
}
class MainMenu extends Component {
selectModule(module) {
this.props.update(module);
}
render() {
console.log(this.props.module);
return (
<Menu>
<Menu.Item onClick={this.selectModule.bind(this, 'targetValue') } >
{ title }
</Menu.Item>
</Menu>
)
}
}
Sharing state with react is sometimes a bit hard.
The react philosophy tends to say that we have to manage state from top to bottom. The idea is to modify the state in your parent, and pass the informations as props. For example, let's imagine the following scenario :
class Main extends React.Component {
contructor(props) {
super(props);
this.state = { currentMenuSelected: 'Home' };
}
onPageChange(newPage) {
this.setState({ currentMenuSelected: newPage });
}
render() {
return(
<div>
<AnotherComponent currentMenu={this.state.currentMenuSelected} />
<MenuWrapper onMenuPress={this.onPageChange} />
</div>
)
}
}
In my example, we tell the MenuWrapper to use the Main.onPageChange when changing page. This way, we're now able to pass that current selected menu to AnotherComponent using props.
This is the first way to manage state sharing using react, and the default one provided by the library
If you want to manage more complex stuff, sharing more state, you should take a look at the flux architecture https://facebook.github.io/flux/docs/overview.html
and the most common implementation of flux : http://redux.js.org/
Store the menu state in the main component, and pass the state updater down to the menu.
This is quite helpful in getting into top-down state
https://facebook.github.io/react/docs/thinking-in-react.html

Categories