2017-05-17 14 views
1

그래서 지금 당장 가지고있는 문제는 첫 번째 클릭에서 내 GUI가 다시 렌더링됩니다. 그러나 두 번째 클릭시 다시 렌더링되지 않습니다. 내 렌더링이 "graphicLayers.map"을 통해 바인딩하는 "graphicLayers"의 상태를 업데이트하지 않기 때문이라고 생각합니다. 즉, 어쨌든 내 이론 (그것의 작동에도 불구하고 첫 번째 클릭?하지만 이후 두번째 클릭 또는 아무것도) 나는 graphicLayers의 setState를 업데이트를 강제로 시도데이터가 변경되지 않은 경우에도 setState를 사용하여 강제로 다시 렌더링 할 수 있습니까? 내 GUI가 업데이트되지 않습니다.

을하지만,이

처럼 .. 작동하지 않는 것
let graphicLayersCopy = Object.assign([], this.state.graphicLayers); 
this.setState({graphicLayers: graphicLayersCopy}); 

하지만 작동하지 않습니다. 나는 디버거를 통해 데이터를 올바르게 설정한다는 것을 알고, 새로 고침 (상태 저장 및 상태 재로드)하면 GUI가 올바르게 렌더링됩니다.

어쨌든 변수를 다시 렌더링하도록 강제 할 수 있습니까? 값을 변경하지 않아도 어떻게됩니까?

생성자

constructor(props, context) { 
    super(props, context); 

    this.state = { 
     graphicLayers: [id1, id2, id3], 
     graphicLayersById: { 
     id1: { ... }, 
     id2: { ... }, 
     id3: { ... } 
     } 

    this.addLayerClick = this.addLayerClick.bind(this); 
}; 

render() { 
    return (  
    <div> 
     {this.state.graphicLayers.map((id) => 
     <GraphicLayer addLayerClick={this.addLayerClick.bind(this)} /> 
    )} 
    </div> 
    ); 
    } 

addLayerClick

addLayerClick() { 
    ... change some property in graphicLayersById dictionary ... 
    self.setState({ graphicLayersById: newDataHere }); 
} 

편집 렌더링 : 얘들 아 그래서 난 내 말에 문제를 발견하고, 정확하게 여기에 표시 아닙니다.

내 addLayerClick() 실제로 호출을 수신하는 다른 함수를 호출하고 내부 상태를 설정합니다. setState가 콜백 함수에서 호출되기 때문에 이상한데, addLayerClick() 자체에 setState를 두어 작동하도록했습니다. 아직도 doens't가 작동하지 않는 이유는 알고 있지만 적어도 여러분 모두를 upvote 할 것입니다.

listenFunction() {

let self = this; 

this.firebaseWrapper.storage.on('graphicLayersById', function (save) { 
    if (save) { 
    self.setState({ graphicLayersById: save }); // FOR SOME REASON THIS DOESN'T UPDATE THE GUI THE 2nd CLICK. The data is correct though and I see it going here on a breakpoint, but GUI won't update unless i setState in the actual button 
    } 
    else { 
    self.setState({ graphicLayersById: undefined }); 
    } 
}); 

} 사실

+0

.bind (this)가 두 번 쓰여집니다. –

+0

@TreefishZhang 의견을 보내 주셔서 감사합니다. 나는 실제로 그것이 문제가되는 것을 발견했을 때 거기에 추가했다. 나는 당신의 코멘트에 기반하여 생성자에서 하나를 남겨 두었지만 그것을 제거했지만 여전히 불행히도 같은 문제를 가지고있다. – user1189352

+0

나는 window.location.reload()를 사용했다. 재 렌더링을 강요하지만 비싸다. 전체 페이지가 다시 그려진다. –

답변

2

는, 당신은 구성 요소에 addLayerClick() 기능을 결합, 그래서 대신 self

this을 사용할 수 있습니다 당신은해야 다음과 같이 코드를 수정 : (약 2 변경이가)

constructor(props, context) { 
    super(props, context); 

    this.state = { 
     graphicLayers: [id1, id2, id3], 
     graphicLayersById: { 
     id1: { ... }, 
     id2: { ... }, 
     id3: { ... } 
     } 
    // don't need to bind here anymore, since you bind it in the click 
    //this.addLayerClick = this.addLayerClick.bind(this); 
}; 

addLayerClick() { 
    //... change some property in graphicLayersById dictionary ... 
    // just use 'this' here 
    this.setState({ graphicLayersById: newDataHere }); 

    // the below line is NOT recommended, which is force the component to update 
    // this.forceUpdate(); // this line will update the component even though there's no change 
} 

를이있는 경우, 덕분에 약간의 오차가 당신이 아이 컴퍼넌트에 onCLick 기능을 처리하는 방법을 여기에 게시하고, 또한 게시하시기 바랍니다, 아직 작동하지 않는 경우

+0

다시 시도해 주셔서 감사합니다. – user1189352

2

는이 두 가지 방법은보기를 reder 희망

this.setState({graphicLayersById: newDataHere} ,()=>{ 
console.log(this.state.graphicLayersById); 
}); 

또는

var update = require('react-addons-update'); 
    var graphicLayers = update(this.state, { 
      graphicLayersById: {$set: newDataHere} 
     }); 
     this.setState(graphicLayers); 
+0

이것을 사용해 주셔서 감사합니다! – user1189352

2

addLayerClick()에서 graphicLayersById 만 업데이트 중이지만 렌더링은 graphicLayers에 따라 달라집니다. 상태를 addLayerClick()으로 업데이트해야합니다.그 모든 렌더링 (및 성능에 영향을 미칠 수)에 새로운 기능을 생성하기 때문에 보조 노트에

addLayerClick() { 
    this.setState({ 
    graphicLayers: ... 
    graphicLayersById: .... 
    }); 
} 

, 당신은 render() 내부의 방법을 결합해서는 안된다. 대신

<GraphicLayer addLayerClick={this.addLayerClick.bind(this)} /> 

<GraphicLayer addLayerClick={this.addLayerClick} /> 

을하고 생성자 (당신이 이미 가지고있는 방식) 바인딩을 둡니다.