通过React Native中的子组件更新父组件

Updating Parent Component via Child Component in React Native

本文关键字:组件 更新 React Native 通过      更新时间:2023-09-26

我有一个父组件和两个子组件。其中一个子组件是一个带有add按钮的窗体。当按下add按钮时,我可以捕捉文本,但在尝试将该值传递给父组件、更新父组件中的数组并重新渲染视图时,我会被卡住。

父组件:

var Tasks = ['Competitor Study','Content Plan','Write','Promote','Consumer Research']
//Build React Component
class MyTaskList extends Component {
render() {
    return (
      <View style={styles.container}>
         <Text style={styles.titleStyle}>
          My Tasks  
          {"'n"} 
            ({Moment().format("MMM Do YY")})
          {"'n"}
        </Text>
        <AddTask />
        {this.workitems()}
      </View>
    );
  }
  workitems() {  
   return (Tasks.map(function(workitem,i) {
    return <ListItem key={i} workitem={workitem} />
        }
      )
    );  
  }
}

形式为的子组件

class AddTask extends Component {
    constructor(props) {
      super(props);
      this.state = {
        enterTask: 'Enter task'
      };
    }
    onTaskTextChanged(event) {
      this.setState({ enterTask: event.nativeEvent.text });
    }
    onAddPress() {
     var newtask = this.state.enterTask;
     console.log('new task - '+newtask);
    }
    render() {
        return (
            <View style={styles.addTask}>
                   <TextInput
                    style={styles.taskInput}
                    value={this.state.enterTask}
                    onChange={this.onTaskTextChanged.bind(this)}
                    placeholder='Enter task'/>
                 <TouchableHighlight style={styles.button}
                    onPress={this.onAddPress.bind(this)}
                    underlayColor='#99d9f4'>
                    <Text style={styles.buttonText}>Add</Text>
                </TouchableHighlight>
            </View>
        );
    }
}

我会使用state,因为不建议使用forceUpdate()

来自React文档:

调用forceUpdate((将导致在组件上调用render((,跳过shouldComponentUpdate((。这将触发子组件的正常生命周期方法,包括每个子组件的shouldComponentUpdate((方法。React仍然只会在标记发生更改时更新DOM。

通常,您应该尽量避免使用forceUpdate((,只从render((中的this.ops和this.state读取。这使得您的组件";纯";并且您的应用程序更加简单高效。

(基于1ven的回答(

父组件:

//Build React Component
class MyTaskList extends Component {
    constructor(props) {
        super(props);
        this.state = {
            tasks: [
                'Competitor Study',
                'Content Plan',
                'Write','Promote',
                'Consumer Research'
            ]
        } 
    }
    handleAddTask(task) {
        var newTasks = Object.assign([], this.state.tasks);
        newTasks.push(task);
        this.setState({tasks: newTasks});
    }
    render() {
        return (
            <View style={styles.container}>
                <Text style={styles.titleStyle}>
                    My Tasks  
                    {"'n"} 
                    ({Moment().format("MMM Do YY")})
                    {"'n"}
                </Text>
                <AddTask onAddTask={this.handleAddTask.bind(this)} />
                {this.workitems()}
            </View>
        );
    }
    workitems() {  
        return this.state.tasks.map(function(workitem,i) {
            return <ListItem key={i} workitem={workitem} />
        });
  
    }
}

形式为的子组件

class AddTask extends Component {
    constructor(props) {
        super(props);
        this.state = {
            enterTask: 'Enter task'
        };
    }
    onTaskTextChanged(event) {
        this.setState({ enterTask: event.nativeEvent.text });
    }
    onAddPress() {
        var newtask = this.state.enterTask;
        console.log('new task - '+newtask);
        // Providing `newtask` variable to callback.
        this.props.onAddTask(newtask);
    }
    render() {
        return (
            <View style={styles.addTask}>
                <TextInput
                    style={styles.taskInput}
                    value={this.state.enterTask}
                    onChange={this.onTaskTextChanged.bind(this)}
                    placeholder='Enter task'/>
                <TouchableHighlight style={styles.button}
                    onPress={this.onAddPress.bind(this)}
                    underlayColor='#99d9f4'>
                   <Text style={styles.buttonText}>Add</Text>
                </TouchableHighlight>
            </View>
        );
    }
}

您应该提供从父组件到子组件的handleAddTask回调:

var Tasks = ['Competitor Study','Content Plan','Write','Promote','Consumer Research']
//Build React Component
class MyTaskList extends Component {
  handleAddTask(task) {
    // When task will be added, push it to array
    Tasks.push(task);
  }
  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.titleStyle}>
          My Tasks  
          {"'n"} 
          ({Moment().format("MMM Do YY")})
          {"'n"}
        </Text>
        <AddTask onAddTask={this.handleAddTask} />
        {this.workitems()}
      </View>
    );
  }
  workitems() {  
    return (
      Tasks.map(function(workitem,i) {
        return <ListItem key={i} workitem={workitem} />
      })
    );  
  }
}

接下来,您应该将任务从子组件传递给这个回调:

class AddTask extends Component {
  constructor(props) {
    super(props);
    this.state = {
      enterTask: 'Enter task'
    };
  }
  onTaskTextChanged(event) {
    this.setState({ enterTask: event.nativeEvent.text });
  }
  onAddPress() {
    var newtask = this.state.enterTask;
    console.log('new task - '+newtask);
    // Providing `newtask` variable to callback.
    this.props.onAddTask(newtask);
  }
  render() {
    return (
      <View style={styles.addTask}>
        <TextInput
          style={styles.taskInput}
          value={this.state.enterTask}
          onChange={this.onTaskTextChanged.bind(this)}
          placeholder='Enter task'/>
        <TouchableHighlight style={styles.button}
          onPress={this.onAddPress.bind(this)}
          underlayColor='#99d9f4'>
          <Text style={styles.buttonText}>Add</Text>
        </TouchableHighlight>
      </View>
    );
  }
}

就是这样。希望,它有帮助!