Call method from child component no work? React and class components - reactjs

I want to call from child component function.
Where I want to call component ? Inside Parent. TO explain better
---Parent( get function from child)
---Child ( from parent call my function )
I am using class component React.
Parent component ->
constructor(props) {
super(props);
this.componentRef = React.createRef();
}
selectedColors = (colors) => {
let { theme, formValuesTheme } = this.props;
this.componentRef.current.handleChange("red");
};
<Field
id="colorDropdown"
name="colorDropdown"
component={renderColorDropdown}
label={intl.formatMessage(messages.colorTheme)}
options={options}
onChange={selectedColors}
/>
Child component ->
class SketchExample extends React.Component {
handleChange = (color) => {
console.log("I NEED BE CALLED FROM PARENT", color);
this.props.input.onChange(color.hex);
};
ERROR message is ->
TypeError: _this.componentRef.current.handleChange is not a function

Related

Parameterizing rendering of parent component from child

I have a Parent component that contains a Child component. Suppose that the Parent wants to ask the Child its preferred background color and uses it to modify how the Parent renders itself:
class Child extends React.Component {
favoriteColor = () => "red";
render = () => (<span>Hello world</span>);
}
class Parent extends React.Component {
render = () => {
const child = (<Child />);
return (
<div style={{backgroundColor: child.favoriteColor()}}>
{child}
</div>
);
};
}
What is the idiomatic way to do this in React?
In my real project, I have a Parent component that has a dynamic set of children. The Parent wraps each child in a React Bootstrap <Col>. But sometimes a child does not want to be rendered, and the correct thing would be to omit the <Col>. So the Parent component needs to be able to ask each child "do you have anything to render?"
One way to do this depending on the circumstances is to declare Child.favoriteColor as static. As a static function it has no access to the instance's props or state.
class Child extends React.Component {
static favoriteColor = () => "red";
render = () => (<span>Hello world</span>);
}
class Parent extends React.Component {
render = () => {
return (
<div style={{backgroundColor: Child.favoriteColor()}}>
<Child />
</div>
);
};
}

React.js - Pass data to parent method as a parameter from child

I am simply trying to pass a value back up to a parent component when I invoke a method in a child component.
I have a parent component called Job. It renders a child component called SummaryChart. When a bar on the barchart is clicked from within SummaryChart, I want it to tell Job which bar was clicked, and to open a modal.
Parent Component
class Job extends Component {
constructor(props)
{
super(props);
this.state = {
...
}
this.getSequenceView = this.getSequenceView.bind(this);
}
getSequenceView(config, event)
{
console.log(config.someData);
$('#help-modal').modal();
}
render()
{
return (
<SummaryChart
handleBarClick={() => this.getSequenceView(config, event)}
/>
);
}
Child Component
class SummaryChart extends Component {
constructor(props) {
super(props);
this.state = {
options: {
chart: {
events: {
dataPointSelection: function(event, chartContext, config) {
props.handleBarClick(config, event);
},
}
}
}
render() {
return (
...
);
}
}
I receive the following error when I click:
Uncaught ReferenceError: config is not defined
I'm thinking my error must lie in my parent component when I pass the prop to SummaryChart, but I don't know how else to tell the method to expect two arguments. Other examples have things like hard-coded props as arguments, but I want to use information from ApexCharts click events to pass back up to the parent.
You're missing the method argument in the child call.
<SummaryChart
handleBarClick={(config, event) => this.getSequenceView(config, event)}
/>

React: Mutating instance of Ref object in child components

class Parent extends React.Component {
constructor(props) {
super(props)
this.data = React.createRef()
}
componentDidMount() {
this.data.current = []
}
render() {
return <Child data={data} />
}
}
const Child = ({ data }) => {
const onDelete = (idx) => {
data.splice(idx, 1)
}
return (
<button onClick={(index) => onDelete(index)}>Delete</button>
)
}
I need this ref to be an array for some complicated to explain reason, although the code is doing the job I am not sure if it is right to mutate the ref prop in the child component. My question is: If the prop I am passing to the child component is not a state in the parent, then is it okay to mutate it? Or in refs case does that work differently? Thanks in advance for any help!

How to pass callback functions with parameters from parent to child components?

I'm really new to ReactJS framework.
I'm trying to pass a callback function from parent to child component.
What i'm trying to pass is a callback function (changeState) to a child component. The child component is a fabric-ui button and this function will be called when clicking on the button.
Parent code : only the necessary code
public constructor(props: {}) {
super(props);
this.state = {
columns: [],
hasError:false,
sortedItems: []
};
this.changeState = this.changeState.bind(this);
}
public changeState = (itemId:React.ReactText)=>{
const resolvedKey='Status';
const idKey='Status';
const item = this.state.sortedItems!.filter(ite => ite[idKey] === itemId)[0];
item[resolvedKey] = 'Résolu';
}
<ResolveButton disabled={isResolved} uniqueId={fieldContent} changeState={this.changeState } />
Child code
import { PrimaryButton } from 'office-ui-fabric-react/lib/Button';
import * as React from 'react';
export interface IHandleChange {
changeState: (itemId:React.ReactText)=>void;
disabled:boolean;
uniqueId:string| number;
}
export class ResolveButton extends React.Component<IHandleChange, {}> {
constructor(props:any) {
super(props);
}
public handleClick = () => {
this.props.changeState(this.props.uniqueId);
alert(`Item ${this.props.uniqueId}`);
}
public render(): JSX.Element {
return (
<div>
{
!this.props.disabled &&
<PrimaryButton
data-automation-id="test"
text="Résolu"
onClick={this.handleClick}
allowDisabledFocus={true}
/>
}
</div>
);
}
}
export default ResolveButton;
The problem is that the child component is not even created when i execute the code above. However the child component is created when i don't pass the callback function (changestate).
This has nothing to do with the parameters disabled and uniqueId passed to the child components. what i'm trying to say is that if i try to remove changeState in the child node interface the child component is well created, however once i introduce changeState in the interface and try to pass it from the parent component the child is never shown in the DOM.
If isResolved variable is not part of the state in parent component, its change will not re-render the tree. It might be the problem.

Passing state to sibling component without using Redux

So I have a component called "itemSelection" which contains a state with a property called "allItems" of type array
constructor(props){
super(props);
this.state = {
allItems: []
}
}
Then I have a component called "methods" which contains a function that returns a value
selectMethod = (e) => {
const x = e.target.getAttribute("data");
this.setState({method: x}, () => console.log(this.state.method));
}
So, What I want to do is to bring the value of propery "method" and push it to the "allItems" array aside with its current state.
The solution is to lift state up: the shared state (here the items) should be kept by the closest ancestor of both components. This ancestor then passes the state to the children via props, along with a callback function that children can use to mutate the state.
For instance in pseudo-code:
class Parent extends React.Component {
constructor(props) {
super(props)
this.state = {
allItems: []
}
this.onSelect = this.onSelect.bind(this)
}
onSelect(item) {
this.setState({allItems: this.state.allItems.push(item)})
}
render() {
return (
<Child1 items={this.state.allItems}/>
<Child2 onSelect={this.onSelect}/>
)
}
}
class Child1 extends React.Component {
render() {
return (
{this.props.items.map(i => i.name)}
)
}
}
class Child2 extends React.Component {
render() {
return (
<button onClick={this.props.onSelect(...)}>button</button>
)
}
}
In the itemSelection component, create a function that will update allItems. Then, pass that function in a property to the method component and call it from there.

Resources