I would like to get the value of the switch inside ToggleCampus from Map.js. How can I update the value of the state inside Map.js from ToggleCampus.js?
Map.js
export default class Map extends React.Component{
constructor(props) {
super(props);
this.state = { switchVal: true};
}
render(){
return (
<ToggleCampus switchVal = {this.state.switchVal} />
);
}
}
ToggleCampus.js
export default class ToggleCampus extends React.Component {
constructor(props){
super(props);
}
render() {
console.log(this.props.switchVal);
return(
<Switch
value={this.props.switchVal}
*(not sure how to use onChange here)*
/>
);
}
}
So basically what you have to do is pass the function as props to ToggleCampus to update the switchVal. Like suppose in ToggleCampus you want to change the value on button click, so check the below method:
Map.js
export default class Map extends React.Component{
constructor(props) {
super(props);
this.state = { switchVal: true};
}
changeSwitch = (value) => {
this.setState({switchVal:value});
}
render(){
return (
<ToggleCampus changeSwitch={this.changeSwitch} switchVal = {this.state.switchVal} /> // passed changeSwitch
);
}
}
and in togglecampus.js
export default class ToggleCampus extends React.Component {
constructor(props){
super(props);
}
render() {
console.log(this.props.switchVal);
return(
<>
<Switch
value={this.props.switchVal}
*(not sure how to use onChange here)*
/>
<Button title="click" onPress={() => this.props.changeSwitch(false)} /> // added this
</>
);
}
}
hope it helps.
I have a box containing a list. The list is made of todoItems. A delete button is next to each item. The button should call the delete method of the box class. Should I pass it to the class List first? Can I call directly the method in the class Box?
class TodoItem extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
handleClick(e)
{
const todoItemId = this.props.todoItemId;
if (!todoItemId)
{
return;
}
this.props.onTodoItemDeleteList({ todoItemId: todoItemId });
}
render() {
return (
<div className="todoItem">
<button onClick={() => this.handleClick()}>delete</button>;
</div>
);
}
}
My List: here the onTodoItemDeleteList is seen in the console, but appears as undefined.
class TodoItemList extends React.Component {
constructor(props) {
super(props);
this.handleItemDeleteList = this.handleItemDeleteList.bind(this);
}
handleItemDeleteList(todoItemId)
{
//call handleItemDelete
}
render() {
if (this.props.data)
{
var todoItemNodes = this.props.data.map(function (todoItem){
return (
<TodoItem todoItemId={todoItem.todoItemId} onTodoItemDeleteList={this.handleItemDeleteList} key={todoItem.todoItemId}>
</TodoItem>
);
});
}
return <div className="todoItemList">{todoItemNodes}</div>;
}
}
My Box: this is where I handle my ajax call to the server.
class TodoItemBox extends React.Component {
constructor(props) {
super(props);
this.state = { data: [] };
this.handleItemDelete = this.handleItemDelete.bind(this);
}
handleItemDelete(todoItemId) {
const data = new FormData();
data.append('todoItemId', todoItemId);
const xhr = new XMLHttpRequest();
xhr.open('post', this.props.deleteUrl, true);
xhr.onload = () => this.loadTodoItemsFromServer();
xhr.send(data);
}
render() {
return (
<div className="todoItemBox">
<TodoItemList data={this.state.data} />
</div>
);
}
}
I solved it by using arrow function in the parent too, it looks like this:
onTodoItemDeleteList={ (todoItemId) => handleItemDeleteList(todoItemId)}
and in the constructor:
handleItemDeleteList = this.handleItemDeleteList.bind(this);
I'm passing a string value from one component class to another and try to update the state in another class
class Dashboard extends Component {
constructor(props) {
super(props);
this.state = {
systemDetailsData: null,
}
}
CalledFromHeader = (systemDetailsData11) => {
this.setState({ systemDetailsData:systemDetailsData11 })
}
}
class Header extends Component {
constructor(props) {
super(props);
Dashboard_Obj = new Dashboard();
}
OnPress = () => {
Dashboard_Obj.CalledFromHeader("system data");
}
}
I'm getting this error ---> Warning: Can't call setState on a component that is not yet mounted. This is a no-op, but it might indicate a bug in your application. Instead, assign to this.state directly or define a state = {}; class property with the desired state in the Dashboard component.
I want to update the state in Dashboard class using above code, Can anyone help me how to achieve this?
Call the Header component in Dashboard render method and pass a function as a prop to Header component.
class Dashboard extends Component {
constructor(props) {
super(props);
this.state = {
systemDetailsData: null,
}
}
CalledFromHeader = (systemDetailsData11) => {
this.setState({ systemDetailsData:systemDetailsData11 })
}
redner(){
return <Header changeState={this.CalledFromheader} />
}
}
class Header extends Component {
constructor(props) {
super(props);
}
render(){
return(
// something view onPress handler
<Button onPress={()=>{
this.props.CalledFromHeader('Some parameters')
}} />
)
}
}
How can a component be moved from one part of the render hierarchy to another while maintaining component state? In the example below, the result of the call to setView creates a new view (as seen by a new instanceValue number), even though I pass what looks like the existing view.
class TestTo extends React.Component {
constructor(props) {
super(props);
this.state = {
instanceValue: parseInt(Math.random() * 100)
}
}
render() {
return <Text>{this.state.instanceValue}</Text>
}
}
class TestFrom extends React.Component {
constructor(props) {
super(props);
this.state = {
view: <TestTo />
}
}
doSet = () => {
this.props.nav.setView(this.state.view);
}
render() {
return <View>
<Button title="doaction" onPress={this.doSet} />
{this.state.view}
</View>
}
}
class Holder extends React.Component {
constructor(props) {
super(props);
this.state = {
view: <TestFrom nav={this} />
}
}
setView = (view) => {
this.setState({view: view});
}
render() {
return this.state.view
}
}
<Holder />
I'm developing my first React Native app. What I'm trying to achieve is to execute a child function from the parent component, this is the situation:
Child
export default class Child extends Component {
...
myfunct: function() {
console.log('Managed!');
}
...
render(){
return(
<Listview
...
/>
);
}
}
Parent
export default class Parent extends Component {
...
execChildFunct: function() {
...
//launch child function "myfunct"
...
//do other stuff
}
render(){
return(
<View>
<Button onPress={this.execChildFunct} />
<Child {...this.props} />
</View>);
}
}
In this example, I would like to log 'Managed!' when I press the button in the parent class. How is it feasible?
Nader Dabit's answer is outdated, since using String literals in ref attributes has been deprecated. This is how we would do it as of September 2017:
<Child ref={child => {this.child = child}} {...this.props} />
<Button onPress={this.child.myfunc} />
Same functionality, but instead of using a String to reference the component, we store it in a global variable instead.
Here's how you can do this with functional components:
Parent
Use useRef() to give the child component a reference in the parent:
const childRef = useRef()
// ...
return (
<ChildComponent ref={childRef} />
)
...
Child
Pass ref as one of the constructor parameters:
const ChildComponent = (props, ref) => {
// ...
}
Import useImperativeHandle and forwardRef methods from the 'react' library:
import React, { useImperativeHandle, forwardRef } from 'react'
Use useImperativeHandle to bind functions to the ref object, which will make these functions accessible to the parent
These methods won't be internally available, so you may want to use them to call internal methods.
const ChildComponent = (props, ref) => {
//...
useImperativeHandle(ref, () => ({
// each key is connected to `ref` as a method name
// they can execute code directly, or call a local method
method1: () => { localMethod1() },
method2: () => { console.log("Remote method 2 executed") }
}))
//...
// These are local methods, they are not seen by `ref`,
const localMethod1 = () => {
console.log("Method 1 executed")
}
// ..
}
Export the child component using forwardRef:
const ChildComponent = (props, ref) => {
// ...
}
export default forwardRef(ChildComponent)
Putting it all together
Child Component
import React, { useImperativeHandle, forwardRef } from 'react';
import { View } from 'react-native'
const ChildComponent = (props, ref) => {
useImperativeHandle(ref, () => ({
// methods connected to `ref`
sayHi: () => { sayHi() }
}))
// internal method
const sayHi = () => {
console.log("Hello")
}
return (
<View />
);
}
export default forwardRef(ChildComponent)
Parent Component
import React, { useRef } from 'react';
import { Button, View } from 'react-native';
import ChildComponent from './components/ChildComponent';
const App = () => {
const childRef = useRef()
return (
<View>
<ChildComponent ref={childRef} />
<Button
onPress={() => {
childRef.current.sayHi()
}}
title="Execute Child Method"
/>
</View>
)
}
export default App
There is an interactive demo of this on Expo Snacks:
https://snack.expo.dev/#backupbrain/calling-functions-from-other-components
This explanation is modified from this TutorialsPoint article
You can add a ref to the child component:
<Child ref='child' {...this.props} />
Then call the method on the child like this:
<Button onPress={this.refs.child.myfunc} />
it is in react. i hope it may help you.
class Child extends React.Component {
componentDidMount() {
this.props.onRef(this)
}
componentWillUnmount() {
this.props.onRef(null)
}
method() {
console.log('do stuff')
}
render() {
return <h1>Hello World!</h1>
}
}
class EnhancedChild extends React.Component {
render() {
return <Child {...this.props} />
}
}
class Parent extends React.Component {
onClick = () => {
this.child.method() // do stuff
};
render() {
return (
<div>
<EnhancedChild onRef={ref => (this.child = ref)} />
<button onClick={this.onClick}>Child.method()</button>
</div>
);
}
}
ReactDOM.render(<Parent />, document.getElementById('root'))
Original Solution:
https://jsfiddle.net/frenzzy/z9c46qtv/
https://github.com/kriasoft/react-starter-kit/issues/909
Simple and easy way to Parent --> Child function call
/* Parent.js */
import React, { Component } from "react";
import { TouchableOpacity, Text } from "react-native";
import Child from "./Child";
class Parent extends React.Component {
onChildClick = () => {
this.child.childFunction(); // do stuff
};
render() {
return (
<div>
<Child onRef={(ref) => (this.child = ref)} />
<TouchableOpacity onClick={this.onChildClick}>
<Text>Child</Text>
</TouchableOpacity>
</div>
);
}
}
/* Child.js */
import React, { Component } from "react";
class Child extends React.Component {
componentDidMount() {
this.props.onRef(this);
}
componentWillUnmount() {
this.props.onRef(undefined);
}
childFunction() {
// do stuff
alert("childFunction called");
}
render() {
return <View>Hello World!</View>;
}
}
Original Solution:
https://github.com/kriasoft/react-starter-kit/issues/909
I think you have misunderstood something about component structure.
Assume that your child is a component which generates button for your other components. In this hierarchy your child has to inform it's parent that it was pressed.
child -----> parent
export default class Child extends Component {
return(
<Button onPress={this.props.onPress } />
);
}
In your parent component use child component to generate a button for you. In this way you can use child component any other components as a independent button.
export default class Parent extends Component {
constructor(props) {
super(props);
this.execChildFunct=this.execChildFunct.bind(this)
}
execChildFunct: function() {
console.log('Managed!');
}
return (
<Child onPress = {this.execChildFunct}></Child>
)
}