2017-05-06 75 views
1

我有一个返回其他组件的任务组件。但是,当我从任务组件中更改某个子组件的状态时,它不会重新渲染。React子组件不会在其上重新呈现状态变化

我将父项中的'newTaskAdded'状态作为道具传递给子元素,并将其分配给子状态以重新呈现子元素,但仍未发生。

我的目标是: 当用户添加任务时,我希望它立即显示在屏幕上,意思是用户必须刷新页面才能看到新任务。

Tasks.jsx:

import React , { Component } from 'react' 
import axios from 'axios' 
import Name from './Name.jsx' 
import ShowTasks from './ShowTasks.jsx' 

class Tasks extends Component { 
    constructor(props) { 
    super(props) 
    this.state={ 
     task: '', 
     newTaskAdded:false, 
     newTask:[], 
    } 
    this.handleChange = this.handleChange.bind(this) 
    this.addTask = this.addTask.bind(this) 
    } 
    handleChange(event) { 
    this.setState({task: event.target.value}) 
    } 
    addTask() { 
    axios.post('/api/addtask',{ 
     name:this.props.name, 
     task:this.state.task 
    }) 
    .then((res) => { 
     if(res.status=='200'){ 
     this.setState ({task:''}) 
     this.setState ({newTaskAdded:true}) 
     this.setState ({newTask: res.data.message[res.data.message.length-1] }) 
     } 
    }) 
    .catch((err) => { 
     if(err) throw err 
    }) 
    } 

    render() { 
    return (
     <div> 
     <div> 
      <Name name={this.props.name} /> 
     </div> 
     <div> 
      <input value={this.state.task} onChange={this.handleChange} type="text" name="task" /> 
      <button type="button" onClick={this.addTask}>Add Task</button> 
     </div> 
     <ShowTasks name={this.props.name} updated={this.state.newTaskAdded} /> 
     </div> 
    ) 
    } 
} 

export default Tasks 

ShowTasks.jsx

import React , { Component } from 'react' 
import axios from 'axios' 
import Completed from './Completed.jsx' 
import NotCompleted from './NotCompleted.jsx' 

class ShowTasks extends Component { 
    constructor(props) { 
    super(props) 
    this.state = { 
     tasks:[], 
     updated:this.props.updated 
    } 
    } 
    componentWillMount(){ 
    axios.post('/api/loadtasks', { 
     name: this.props.name 
    }) 
    .then((res) => { 
     console.log('res', res); 
     this.setState ({tasks:res.data.tasks}) 
    }) 
    .catch((err) => { 
     throw err 
    }) 
    } 
    render() { 
    return (
     <div className='pointer'> 
     {this.state.tasks.map((task) => { 
      if(task.completed) { 
      return <Completed key={task._id} {...task} /> 
      } 
      else { 
      return <NotCompleted key={task._id} {...task} /> 
      } 
     })} 
     </div> 
    ) 
    } 
} 

export default ShowTasks 
+0

确实正在执行的'then'一部分?你有控制台日志吗? – Chris

+0

Duplicate:http://stackoverflow.com/a/41971336/3734057 – absolutezero

+0

感谢您的回复@Chris。它确实工作 – EJ92

回答

0

所以,问题是你的孩子的功能,你正在设置道具状态,

要设置道具状态,并且在每次道具更改时都不会调用构造函数,但仅在组件呈现时第一次调用,因此状态不会更新为正确的值。

您应该设置在componentWillReceiveProps功能的道具是呼吁每一个渲染父组件的

class ShowTasks extends Component { 
    constructor(props) { 
    super(props) 
    this.state = { 
     tasks:[], 
     updated:this.props.updated 
    } 
    } 
    componentWillReceiveProps(nextProps) { 
     this.setState({updated: nextProps.updated}); 
    } 
    componentWillMount(){ 
    axios.post('/api/loadtasks', { 
     name: this.props.name 
    }) 
    .then((res) => { 
     console.log('res', res); 
     this.setState ({tasks:res.data.tasks}) 
    }) 
    .catch((err) => { 
     throw err 
    }) 
    } 
    render() { 
    return (
     <div className='pointer'> 
     {this.state.tasks.map((task) => { 
      if(task.completed) { 
      return <Completed key={task._id} {...task} /> 
      } 
      else { 
      return <NotCompleted key={task._id} {...task} /> 
      } 
     })} 
     </div> 
    ) 
    } 
} 

export default ShowTasks 

了解更多关于生命周期的功能以及何时使用它们here:

+0

嗨,感谢您的快速响应。但它仍然无法正常工作。 componentWillMount函数未被访问。 – EJ92

+0

componentWillMount是什么意思没有被访问 –

0

OK !解决:

Tasks.jsx:

import React , { Component } from 'react' 
import axios from 'axios' 
import Name from './Name.jsx' 
import ShowTasks from './ShowTasks.jsx' 

class Tasks extends Component { 
    constructor(props) { 
    super(props) 
    this.state={ 
     user:this.props.user, 
     task:'', 
     newTask:[], 
    } 
    this.handleChange = this.handleChange.bind(this) 
    this.addTask = this.addTask.bind(this) 
    } 

    handleChange(event) { 
    this.setState({task: event.target.value}) 
    } 

    addTask() { 
    axios.post('/api/addtask',{ 
     name:this.state.user.name, 
     task:this.state.task 
    }) 
    .then((res) => { 
     if(res.status=='200'){ 
     this.setState ({user:this.state.user}) 
     this.setState ({newTask: res.data.message[res.data.message.length-1] }) 
     } 
    }) 
    .catch((err) => { 
     if(err) throw err 
    }) 
    } 

    render() { 
    return (
     <div> 
     <div> 
      <Name name={this.props.user.name} /> 
     </div> 
     <div> 
      <input value={this.state.task} onChange={this.handleChange} type="text" name="task" /> 
      <button type="button" onClick={this.addTask}>Add Task</button> 
     </div> 
     <ShowTasks user={this.state.user}/> 
     </div> 
    ) 
    } 
} 

export default Tasks 

ShowTasks.jsx:

import React , { Component } from 'react' 
import axios from 'axios' 
import Completed from './Completed.jsx' 
import NotCompleted from './NotCompleted.jsx' 

class ShowTasks extends Component { 
    constructor(props) { 
    super(props) 
    this.state = { 
     user: this.props.user, 
     tasks:[], 
    } 
    this.loadTasks=this.loadTasks.bind(this) 
    } 

    loadTasks() { 
    axios.post('/api/loadtasks', { 
     name: this.state.user.name 
    }) 
    .then((res) => { 
     this.setState ({tasks:res.data.tasks}) 
    }) 
    .catch((err) => { 
     throw err 
    }) 
    } 

    componentWillReceiveProps(nextProps) { 
    this.loadTasks() 
    } 

    render() { 
    return (
     <div className='pointer'> 
     {this.state.tasks.map((task) => { 
      if(task.completed) { 
      return <Completed key={task._id} {...task} /> 
      } 
      else { 
      return <NotCompleted key={task._id} {...task} /> 
      } 
     })} 
     </div> 
    ) 
    } 
} 

export default ShowTasks 
相关问题