Don't change the state in my component - React - reactjs

I'm trying to change the state the a child component but don't change, this is the parent component:
export default class History extends Component {
constructor(props) {
super(props);
this.state = {
histories : JSON.parse(JSON.stringify(histories)),
counter: 1,
id: ''
}
}
increaseCounter = () => {
this.setState({counter: this.state.counter+1})
}
showIdHistory = (id) => {
this.setState(() => {return {id:id}})
}
render() {
return (
<div className="history">
<div>
<h3 className='titleHistory'>{searchHistoryById(this.state.id,this.state.counter)}</h3>
</div>
<div className='options'>
<div className='option'>
<BottonOptionA option='A' increaseCounter={this.increaseCounter} showIdHistory={this.showIdHistory}/>
<h2>{searchOptionById('a',this.state.counter+this.state.id)}</h2>
</div>
<div className='option'>
<BottonOptionB option='B' increaseCounter={this.increaseCounter} showIdHistory={this.showIdHistory}/>
<h2>{searchOptionById('b',this.state.counter+this.state.id)}</h2>
</div>
</div>
<div className='sectionStatics'>
<SelectionBefore optionAnterior={this.state.id}/>
<reacordOfOptions option={this.state.id}/>
</div>
</div>
);
}
}
i want that the parent component pass the state to the component called SelectionBefore but when the parent child changes the state, the props of SelectionBefore still is the same
this is the component child:
import React,{Component} from 'react'
export default class SelectionBefore extends Component {
constructor(props) {
super(props)
this.state = {
optionBefore : props.optionBefore,
}
}
render() {
return (
<div >
<p> Seleccion anterior: {this.state.optionBefore}</p>
</div>
)
}
}

Try following changes :
Child component
import React,{Component} from 'react'
export default class SelectionBefore extends Component {
constructor(props) {
super(props);
}
render() {
return (
<div >
<p> Seleccion anterior: {this.props.optionAnterior}</p>
</div>
)
}
}
I have directly used the props which is passed by parent to the child .
This means that , whenever state of parent changes , your child will rerender and the changes will be shown .

Related

How to change title from child component to parent component without hooks?

I have two components child and parent. And I want to change the title of the parent component from the child component. But without hooks.
So I have this:
class App extends Component {
render() {
return (
<div className="app">
<ParentComponent/>
</div>
);
}
}
export default App;
and child component:
import React from 'react'
function ChildComponent(props) {
return (
<div>
<h1>Child COmponent</h1>
<button onClick={() => props.greetHandler('Niels')}>Greet parent</button>
</div>
)
}
export default ChildComponent;
and parent component:
class ParentComponent extends Component {
constructor(props) {
super(props);
this.state = {
parentName: 'parent'
};
this.greetParent = this.greetParent.bind(this);
}
greetParent(childname) {
`${childname}`;
}
render() {
return (
<div>
<h1>{this.state.parentName}</h1>
<ChildComponent greetHandler={this.greetParent} />
</div>
)
}
}
export default ParentComponent;
But nothing happens And I got the message:
./src/ParentComponent.js
Line 19: Expected an assignment or function call and instead saw an expression no-unused-expressions
So my question: what I have to change that the title of parent component will change to Niels
you should change the state in greetParent function
greetParent(childname) {
this.setState({
parentName: childname
})
}

How to get the DOM ref of a child class component in a parent class component

I'm having a hard time understanding the docs on how to access the DOM ref of a child class component from the parent class component.
Parent.js:
import Child from './Child';
class Parent extends Component {
constructor(props) {
super(props);
this.refOfTheParent = React.createRef();
}
componentDidMount() {
const parentDOM = this.refOfTheParent.current;
//const childDOM = ???;
}
render() {
return (
<div ref={this.refOfTheParent}>
<Child />
</div>
);
}
}
export default Parent;
Child.js:
class Child extends Component {
render() {
return (
<div>Child component</div>
);
}
}
export default Child;
Could someone please finish this code for me where childDOM in Parent::componentDidMount() has the DOM ref of <Child />.
Bonus: How would it look if Parent AND Child are both connected with react-redux connect.
You can use forwardRef
class Child extend React.Component{
render() {
return (
<div ref={this.props.forwardRef}> Child component </div>
)
}
}
export default React.forwardRef((props, ref) => <Child {...props} forwardRef={ref} />)
Then in parent
constructor(props) {
// ...
this.childRef = React.createRef();
}
render() {
return (
<div>
<Child ref={this.childRef} />
</div>
)
}
more info here
you can pass the ref in props in child component like
import React,{Component} from 'react';
import Child from './Child';
class Parent extends Component {
constructor(props) {
super(props);
this.refOfTheParent = React.createRef();
this.childRef=React.createRef();
}
componentDidMount() {
const parentDOM = this.refOfTheParent.current;
const childDom=this.childRef.current;
console.log(childDom);
//const childDOM = ???;
}
render() {
return (
<div ref={this.refOfTheParent}>
<Child childRef={this.childRef}/>
</div>
);
}
}
export default Parent
Child Component
import React,{Component} from 'react';
class Child extends Component {
render() {
return (
<div ref={this.props.childRef} id="1">Child component</div>
);
}
}
export default Child;
Demo

Typescript + React call parent method from child component

I am trying to call parent method from child component, but it doesn't work and method in parent element is not triggered. In this example I have only two components where ChildHello calls method in Hello component.
codesandbox
Hello.tsx
import * as React from "react";
interface Props {
itemClicked: () => void;
}
export class Hello extends React.Component<Props, {}> {
constructor(props: Props) {
super(props);
}
itemClicked = val => {
console.log(val);
};
render() {
const { name } = this.props;
return <h1 itemClicked={this.itemClicked}>{this.props.children}</h1>;
}
}
const styles = {
height: "400px"
};
export class ChildHello extends React.Component<Props, {}> {
constructor(props: Props) {
super(props);
}
render() {
return (
<div onClick={this.props.itemClicked} style={styles}>
<Hello>Hello Child</Hello>
</div>
);
}
}
You need to understand parent child relationship
in childHello you are using the click event.
<div onClick={this.props.itemClicked} style={styles}>
<Hello>Hello Child</Hello>
</div>
childhello is called by the index.jsx page
<div style={styles}>
<ChildHello name="CodeSandbox" />
</div>
Here you are not passing any click events. also, hello component is inside the child component which is wrong.
All the parent component should have click method involved and that method should be passed as props.
Like this
Parent:
<div style={styles}>
<Hello name="CodeSandbox" />
</div>
Hello component
render() {
const { name } = this.props;
return <ChildHello itemClicked={this.itemClicked} />;
}
ChildHello
render() {
return (
<div onClick={this.props.itemClicked} style={styles}>
Hello
</div>
);
}
Sandbox demo

passing state of child component

So I have a component "itemSelection" and inside of it I map through an api response like this
<div className="row">
{this.state.items.map(i => <Item name={i.name} quantity={i.quantity} />)}
</div>
Here the state of "Item" component
constructor(props){
super(props);
this.state = {
visible: false,
selected: false,
}
}
How could I pass the state of "Item" component to "itemSelection" component?
Sending data back up to your parent component should be done by using props.
Fairly common question, see this post for the long answer.
As according to me, If I understood your question you want to call the state of the child component to the parent component.
//Child.js
import s from './Child.css';
class Child extends Component {
getAlert() {
alert('clicked');
}
render() {
return (
<h1 ref="hello">Hello</h1>
);
}
}
export default withStyles(s)(Child);
//Parent.js
class Parent extends Component {
render() {
onClick() {
this.refs.child.getAlert()
}
return (
<div>
<Child ref="child" />
<button onClick={this.onClick.bind(this)}>Click</button>
</div>
);
}
}
Also, you can get the code reference from the link: https://github.com/kriasoft/react-starter-kit/issues/909
This a little tricky but Maybe, its help you solving your problem.
//Parent.js
class Parent extends Component {
component(props) {
super(props)
this.state = {
test: 'abc'
}
}
ParentFunction = (value) => {
this.state.test = value;
this.setState(this.state);
}
render() {
return (
<div>
<Child
test={this.state.test}
ParentFunction={this.ParentFunction}
/>
</div>
);
}
}
//Child.js
import s from './Child.css';
class Child extends Component {
component(props) {
super(props)
this.state = {
test: props.test
}
}
handleChange = () => {
this.state.test = event.target.value;
this.setState(this.state);
this.handleOnSave()
}
handleOnSave = () => {
this.props.ParentFunction(this.state.test);
}
render() {
return (
<div>
<input type="text" onChange={this.handleChange} />
</div>
);
}
}
export default withStyles(s)(Child);

Reactjs parent component communicate with child of child component

i'm using ReactJS without FLux or Redux. I want the grand child component can communicate (read/update data) with his grandparents component.
Here's the parent component App:
export default class App extends React.Component {
static propTypes = {
children: React.PropTypes.object.isRequired
};
constructor(props) {
super(props);
this.state = {
tabActive: 0,
};
}
setTabActive(item) {
this.setState({
tabActive: item,
});
}
render() {
return (
<div>
<Header tabActive={this.state.tabActive} />
<Content>
{this.props.children}
</ Content>
<Footer />
</div>
);
}
}
child component Header:
export default class Header extends React.Component {
render() {
return (
<div>
....
<SettingTabBar tabActive={this.props.tabActive} />
</div>
);
}
}
Child of child component SettingTabBar:
export default class SettingTabBar extends React.Component {
constructor(props) {
super(props);
this.state = { activeTab: this.props.tabActive };
}
render() {
if (location.pathname.indexOf('setting') > 0) {
return (
<Tabs activeTab={this.state.activeTab} onChange={tabId => this.setState({ activeTab: tabId })} ripple>
<Tab>SETTING</Tab>
<Tab>CHARTS</Tab>
<Tab>HELP</Tab>
</Tabs>
);
}
return null;
}
}
Are there anyway to make SettingTabBar component can update data to App/Header component via function setTabActive() when onChange?
For communication with grandparent and grandchild, you can use context. It's not recomended, but it's working.
// root component
class App extends React.Component {
constructor(props){
super(props);
this.state = {
activeMenu: "none"
};
}
getChildContext() {
return {
rootCallback: menuName => {
this.setState({activeMenu: menuName});
}
}
}
render() {
return (
<div>
<div>Current active menu is: <strong>{this.state.activeMenu}</strong></div>
<Child />
</div>
);
}
}
// declare childContextTypes at context provider
App.childContextTypes = {
rootCallback: React.PropTypes.function
}
// intermediate child
class Child extends React.Component {
render() {
return (
<div>
<GrandChild />
</div>
);
}
}
// grand child
class GrandChild extends React.Component {
render() {
return (
<div>
{/* get context by using this.context */}
<button
type="button"
onClick={()=>this.context.rootCallback("one")}
>
Activate menu one
</button>
<button
type="button"
onClick={()=>this.context.rootCallback("two")}
>
Activate menu two
</button>
<button
type="button"
onClick={()=>this.context.rootCallback("three")}
>
Activate menu three
</button>
</div>
)
}
}
// also declare contextTypes at context consumer
GrandChild.contextTypes = {
rootCallback: React.PropTypes.function
}
// render it to DOM
ReactDOM.render(<App /> , document.getElementById('app-mount'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app-mount"></div>

Resources