2016-09-28 22 views
3

背景: 我试图用反应更新基于一些Web服务的JSON响应一些UI元素,但因为我有很多的元素如果元素的HashCode被更新,我试图通过只拉json来减少带宽。在我的应用程序的上下文中,我无法更新我的ajax调用的异步行为。只有在异步调用完成后,强制更新元素的正确方法是什么?
我意识到WillUpdate中的设置状态是错误的。阵营:异步调用之前最后的渲染方法被调用更新状态

例子:

getInitialState: function getInitialState() { 
     return { hash: 0, json: {}}; 
    }, 

    //Only get the step asJSON if the hash is updated 
    shouldComponentUpdate: function(nextProps, nextState) { 
     return this.state.json.hash != nextState.json.hash; 
    }, 

    tick: function(){ 
     this.updateHash(); 
    }, 

    updateHash: function updateHash(){ 
     something.getUpdateHash(function(data){ 
      var hashR = data.responseJSON; 
      this.setState({hash: hashR}); 
     }.bind(this)); 
    }, 

    updateJSON: function(){ 
     //This is an asynchronous call 
     something.getJSON(function(data){ 
      var stepJ = jQuery.parseJSON(data.responseJSON); 
      this.setState({json: stepJ}); 
     }.bind(this)); 
    }, 

    componentWillMount: function(){ 
     this.updateJSON(); 
    }, 

    componentDidMount: function(){ 
     this.interval = setInterval(this.tick, 10000); 
    }, 

    componentWillUpdate: function(nextState, nextProps){ 
     //Way to update json state w/o affecting state? 
    }, 

    render: function render() { 
     /** Only do render after updateJSON is complete **/ 
    } 

回答

1

如何调用updateJSONupdateHash

updateHash: function updateHash(){ 
    something.getUpdateHash(function(data){ 
     var hashR = data.responseJSON; 
     if(hashR!==this.state.hash){ 
      this.updateJSON(hashR) 
     } 
    }.bind(this)); 
}, 

updateJSON: function(hash){ 
    //This is an asynchronous call 
    something.getJSON(function(data){ 
     var stepJ = jQuery.parseJSON(data.responseJSON); 
     this.setState({json: stepJ,hash}); 
    }.bind(this)); 
}, 
+0

我没有想到这个!谢谢+1 – Chrizt0f

1

如果我理解正确,你是想更新只有一些动作(检查哈希)DOM的回调将来会发生。我发现从显示逻辑的容器中抽出这种逻辑更有帮助,并且导致使用很多无状态的组件,而我发现这些组件更容易推理。

// The component that you are housing everything in now 
// seconds would be your JSON 
const ActualDisplay = ({seconds}) => <div>It has been {seconds} since started</div> 

class App extends React.Component { 
    constructor(props){ 
    super(props) 
    this.state = { 
     seconds: 0 
    } 
    } 
    // This is so we can mimic the future checks 
    componentWillMount(){ 
    let seconds = this.state.seconds 
    setInterval(()=>{ 
     this.maybeUpdate(seconds) 
     seconds++ 
    },1000) 
    }; 
    // This is where you say 'if my hash is different, set state' 
    maybeUpdate = (seconds) =>{ 
    console.log(seconds) 
    if(seconds % 10 === 0){ 
     this.setState({ 
     seconds 
     }) 
    } 
    }; 

    render() { 
    // And because we are updating the state of THIS container 
    // we can just say 'Hey, whatever the state is of this, pass it down 
    return <ActualDisplay seconds={this.state.seconds} /> 
    } 
} 

ReactDOM.render(
    <App />, 
    document.getElementById('mount') 
) 
+1

有趣的方法!我看到你如何将秒的状态从“更新”范围内移除为“仅反应”。在我的例子中,秒模将被替换为一些wasHashUpdated逻辑。我更喜欢使用回调的原因是为了维护响应api的'模子'(例如didMount,tick等),并进一步强制执行hashUpdate - > jsonUpdate关联 – Chrizt0f