Javascript 在React Native中通过子组件更新父组件

Javascript 在React Native中通过子组件更新父组件,javascript,react-native,components,parent-child,Javascript,React Native,Components,Parent Child,我有一个父组件和两个子组件。子组件之一是带有add按钮的表单。当按下add按钮时,我能够捕获文本,但在尝试将该值传递给父组件、更新父组件中的数组并重新渲染视图时,文本被卡住 父组件: var Tasks = ['Competitor Study','Content Plan','Write','Promote','Consumer Research'] //Build React Component class MyTaskList extends Component { render()

我有一个父组件和两个子组件。子组件之一是带有
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} />
        }
      )
    );  
  }

}
//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} />
        });
  
    }
}
var Tasks=['Competitor Study'、'Content Plan'、'Write'、'promotion'、'Consumer Research']
//构建反应组件
类MyTaskList扩展了组件{
render(){
返回(
我的任务
{“\n”}
({Moment().format(“MMM Do YY”)})
{“\n”}
{this.workitems()}
);
}
工作项(){
return(Tasks.map)(函数(workitem,i){
返回
}
)
);  
}
}
具有表单的子组件

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>
        );
    }
}
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>
        );
    }
}
class AddTask扩展组件{
建造师(道具){
超级(道具);
此.state={
输入任务:“输入任务”
};
}
onTaskTextChanged(事件){
this.setState({enterTask:event.nativeEvent.text});
}
onAddPress(){
var newtask=this.state.enterTask;
log('newtask-'+newtask);
}
render(){
返回(
添加
);
}
}

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

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} />
      })
    );  
  }
}
var Tasks=['Competitor Study'、'Content Plan'、'Write'、'promotion'、'Consumer Research']
//构建反应组件
类MyTaskList扩展了组件{
手动任务(任务){
//将添加任务时,将其推送到阵列
任务。推送(任务);
}
render(){
返回(
我的任务
{“\n”}
({Moment().format(“MMM Do YY”)})
{“\n”}
{this.workitems()}
);
}
工作项(){
返回(
Tasks.map(函数(工作项,i){
返回
})
);  
}
}
接下来,您应该将任务从子组件传递到此回调:

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>
    );
  }
}
class AddTask扩展组件{
建造师(道具){
超级(道具);
此.state={
输入任务:“输入任务”
};
}
onTaskTextChanged(事件){
this.setState({enterTask:event.nativeEvent.text});
}
onAddPress(){
var newtask=this.state.enterTask;
log('newtask-'+newtask);
//向回调函数提供'newtask'变量。
this.props.onAddTask(newtask);
}
render(){
返回(
添加
);
}
}

就这样。希望有帮助

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

从React文档:

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

通常,您应该尽量避免使用forceUpdate(),而只从render()中的this.props和this.state读取。这使您的组件变得“纯粹”,应用程序变得更加简单和高效

(基于@1ven答案)

父组件:

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} />
        }
      )
    );  
  }

}
//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} />
        });
  
    }
}
//构建反应组件
类MyTaskList扩展了组件{
建造师(道具){
超级(道具);
此.state={
任务:[
“竞争对手研究”,
“内容计划”,
“写”、“促进”,
“消费者研究”
]
} 
}
手动任务(任务){
var newTasks=Object.assign([],this.state.tasks);
newTasks.push(任务);
this.setState({tasks:newTasks});
}
render(){
返回(
我的任务
{“\n”}
({Moment().format(“MMM Do YY”)})
{“\n”}
{this.workitems()}
);
}
工作项(){
返回this.state.tasks.map(函数(workitem,i){
返回
});
}
}
具有表单的子组件

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>
        );
    }
}
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>
        );
    }
}
class AddTask扩展组件{
建造师(道具){
超级(道具);
此.state={
输入任务:“输入任务”
};
}
onTaskTextChanged(事件){
this.setState({enterTask:event.nativeEvent.text});
}
onAddPress(){
var newtask=this.state.enterTask;
log('newtask-'+newtask);
//向回调函数提供'newtask'变量。
this.props.onAddTask(newtask);
}
render(){
返回(
添加
);
}
}

太棒了!它正在将新条目添加到数组中。知道如何重新呈现视图以显示更新的数组吗?@user709413,当然,在按下数组后运行
this.forceUpdate()
。当我按下“添加”按钮时出现以下错误-未处理的JS异常:undefined不是对象(评估'this.state.Tasks')。尝试小写的“Tasks”:
this.state.Tasks
:):(出现以下错误-this.props.onAddTask不是函数。(在“this.props.onAddTask(newtask)”中,“this.props.onAddTask”未定义)我的错!我一定是复制了错误的代码-我更新了答案中的示例-忘记将
onAddTask
道具添加到
MyTaskList
中的
AddTask
组件中。感谢您的帮助。使用了您提供的确切代码,但未处理的JS异常:undefined不是对象(评估“this.state.tasks”)。