2017-07-07 24 views
2

我有一個ReactJS項目,我從REST Django主機獲取JSON併爲其創建一個帶有過濾器的表。我有一個表類:如何僅當我更改類道具時加載組件

class MainTable extends React.Component { 

    constructor(props) { 
    super(props); 
    this.state = { 
     results: [] 
    }; 
    } 

    componentDidMount(){ 
    axios.get(this.props.link) 
     .then(res => { 
     this.setState({results: res.data.results}); 
    }); 
    } 

    render() { 
    return (
     <Table hover striped bordered responsive size="sm"> 
     <thead> 
      <tr> 
      <th>Name</th> 
      <th>Name</th> 
      </tr> 
     </thead> 
     <tbody> 
      {this.state.results.map(result => 
      <tr key={result.fileId}> 
       <td>{result.Name}</td> 
       <td>{result.Name}</td> 
      </tr> 
     )} 
     </tbody> 
     </Table> 
    ); 
    } 
} 

而且主要在哪裏運行所有過濾器類:

class Main extends React.Component { 
    constructor() { 
    super(); 
    this.state = { 
     origin: '', 
     limit: 10 
    }; 

    this.handleChangeOrigin = this.handleChangeOrigin.bind(this); 
    this.handleChangeLimit = this.handleChangeLimit.bind(this); 
    } 

    handleChangeLimit(event) { 
    this.setState({limit: event.target.value}); 
    } 
    handleChangeOrigin(event) { 
    this.setState({origin: event.target.value}); 
    } 

    render() { 
    var link = `http://106.120.89.142:8000/database/?limit=${this.state.limit}&`; 
    if (this.state.origin){ 
     link += `ORIGIN=${this.state.origin.toLowerCase()}`; 
     console.log(link) 
    } 
    return (
     <div> 
     <div> 
      <h1 className="jumbotron-heading display-4">Here u got database *_*</h1> 
     </div> 
     <div> 
      <Limit handleChange = {this.handleChangeLimit} /> 
     </div> 
     <div> 
      <OriginRow handleChange = {this.handleChangeOrigin} /> 
     </div> 
     <div id="tableWrapper"> 
      <MainTable link={link} /> 
     </div> 
     </div> 
    ); 
    } 
} 

,我已經出了問題,因爲當我使用componentDidMount(),我axios.get(my link to REST JSON)只運行一次。當我在Table class render()中使用axios時,它每秒鐘觸發我的服務器幾次。只有當我的表格類的道具改變時,我纔可以進行安裝嗎?

+0

*「只有當我的表格類的道具改變了,我才能進行安裝嗎?」 - 你的意思是'TableMain'組件嗎?因爲'Table'是一個react-bootsrap組件。 – Chris

+0

'MainTable類',正好。對不起,我可以更精確。 –

回答

0

您應該查看shouldComponentUpdate()生命週期方法here

shouldComponentUpdate()

shouldComponentUpdate(nextProps, nextState) 

使用shouldComponentUpdate()讓陣營知道,如果一個組件的輸出不會受到州或道具的電流變化。默認行爲是在每次狀態更改時重新呈現,在絕大多數情況下,您應該依賴默認行爲。

shouldComponentUpdate()在渲染時會在接收到新的道具或狀態時調用。默認爲true。此方法不用於初始渲染或使用forceUpdate()


添加下面的代碼片段到你的MainTable組件。這將阻止它重新渲染,除非props已更改。

shouldComponentUpdate(nextProps) { 
    return JSON.stringify(this.props) !== JSON.stringify(nextProps); 
} 

這將檢查所有道具。如果您想檢查針對具體道具,你可以這樣做:

shouldComponentUpdate(nextProps) { 
    return JSON.stringify(this.props.link) !== JSON.stringify(nextProps.link); 
} 

正如在評論中指出,總有一個的機會,JSON.stringify(this.props) !== JSON.stringify(nextProps)將返回false甚至當他們等於。因此,如果您想要將this.props對象與newProps對象進行比較的方法更爲穩健,則應該查看this post

+0

'JSON.stringify'在按鍵順序中不穩定,所以這會引入一個錯誤。至少有一個錯誤,在這種情況下,通常會導致不需要的重新渲染。 –

+0

非常感謝你,但還有一個問題。如何在開始時運行我的'MainTable',我現在過濾之前得到一個空的'Table',並且我想像之前那樣獲取所有數據庫。 –

+0

JavaScript中的對象沒有排序,並且stringify也不排序,所以你只是依賴未定義的行爲。請參閱https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify –

4

正如您指出的那樣,您可以實現shouldComponentUpdate。另外,如果你不需要一個比較深的,即在任何集合或對象,只是使用的,而不是組件PureComponent:

https://github.com/facebook/react/blob/master/docs/docs/reference-react.md

React.PureComponent# React.PureComponent酷似React.Component但實現shouldComponentUpdate( )與淺色道具和狀態比較。

1

感謝您的幫助,我發現並選擇最佳的解決方案是:

componentDidMount() { 
    axios.get(this.props.link) 
     .then(res => { 
     this.setState({results: res.data.results, count: res.data.count}); 
    }); 
    } 

    componentWillReceiveProps(nextProps) { 
    axios.get(nextProps.link) 
     .then(res => { 
     this.setState({results: res.data.results, count: res.data.count}); 
    }); 
    } 

這正是我需要的,你可以在這裏讀到它:https://facebook.github.io/react/docs/react-component.html#componentwillreceiveprops。每次我收到新的props時,它都會重新運行我的render(),並且我沒有在我的render中使用axios,這更具吸引力。

相關問題