2017-05-06 77 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 
相關問題