sourcetip

상태 변경 시 반응 구성 요소가 다시 렌더링되지 않음

fileupload 2023. 4. 3. 21:41
반응형

상태 변경 시 반응 구성 요소가 다시 렌더링되지 않음

콘텐츠를 얻기 위해 API로 이동하는 리액트 클래스가 있습니다.데이터가 반환되는 것을 확인했지만 다시 렌더링되지 않습니다.

var DealsList = React.createClass({
  getInitialState: function() {
    return { deals: [] };
  },
  componentDidMount: function() {
    this.loadDealsFromServer();
  },
  loadDealsFromServer: function() {
    var newDeals = [];

    chrome.runtime.sendMessage({ action: "findDeals", personId: this.props.person.id }, function(deals) {
      newDeals = deals;
    });

    this.setState({ deals: newDeals });
  },
  render: function() {
    var dealNodes = this.state.deals.map(function(deal, index) {
      return (
        <Deal deal={deal} key={index} />
      );
    });
    return (
      <div className="deals">
        <table>
          <thead>
            <tr>
              <td>Name</td>
              <td>Amount</td>
              <td>Stage</td>
              <td>Probability</td>
              <td>Status</td>
              <td>Exp. Close</td>
            </tr>
          </thead>
          <tbody>
            {dealNodes}
          </tbody>
        </table>
      </div>
    );
  }
});

단, 다음 명령어를 추가할 경우debugger아래와 같이newDeals이 입력되어 있고, 계속 진행하면 데이터가 표시됩니다.

  loadDealsFromServer: function() {
    var newDeals = [];

    chrome.runtime.sendMessage({ action: "findDeals", personId: this.props.person.id }, function(deals) {
      newDeals = deals;
    });
    debugger
    this.setState({ deals: newDeals });
  },

콜링 딜 리스트는 다음과 같습니다.

var Gmail = React.createClass({
  render: function() {
    return (
      <div className="main">
        <div className="panel">
          <DealsList person={this.props.person} />
        </div>
      </div>
    );
  }
});

여기에 엄청나게 간단한 것을 덧붙이고 싶지만, 오, 너무 쉽게 글을 쓰는 실수를 했어요.

this.state.something = 'changed';

...그리고 왜 렌더링과 구글 검색 및 이 페이지가 뜨지 않는지 이해하지 못했는데, 다음과 같이 썼어야 했다는 것을 깨달았습니다.

this.setState({something: 'changed'});

React는 다음을 사용하는 경우에만 재렌더를 트리거합니다.setState상태를 갱신합니다.

제 시나리오는 조금 달랐어요.그리고 나는 나 같은 많은 신입생들이 당황할 것이라고 생각한다 - 그래서 여기서 공유한다.

my state 변수는 다음과 같이 useState를 사용하여 관리되는 JSON 개체의 배열입니다.

const [toCompare, setToCompare] = useState([]);

단, 아래 함수와 같이 toCompare를 setToCompare로 업데이트하면 re-render가 실행되지 않습니다.그리고 다른 부품으로 옮기는 것도 효과가 없었습니다.다른 이벤트가 재발송되는 경우에만 갱신된 리스트가 표시되었습니다.

const addUniversityToCompare = async(chiptoadd) =>
  {
      var currentToCompare = toCompare;
      currentToCompare.push(chiptoadd);
      setToCompare(currentToCompare);
  }

이게 제 해결책이었어요.기본적으로 어레이를 할당하는 것은 참조를 복사하는 것이며, 어레이에 대한 참조는 변경되지 않기 때문에 어레이 내의 콘텐츠만 변경으로 간주되지 않습니다.다음 코드에서는 슬라이스를 사용하여 어레이를 복사하고 변경 없이 변경 후 다시 할당했습니다.완벽하게 잘 작동합니다.

const addUniversityToCompare = async (chiptoadd) => {
    var currentToCompare = toCompare.slice();
    currentToCompare.push(chiptoadd);
    setToCompare(currentToCompare);
}

그게 나 같은 사람에게 도움이 됐으면 좋겠어.제가 틀렸다고 느끼거나 다른 방법이 있다면 알려주세요.

잘 부탁드립니다.

그 이유는 그 응답은chrome.runtime.sendMessage는 비동기적입니다.조작 순서는 다음과 같습니다.

var newDeals = [];

// (1) first chrome.runtime.sendMessage is called, and *registers a callback*
// so that when the data comes back *in the future*
// the function will be called
chrome.runtime.sendMessage({...}, function(deals) {
  // (3) sometime in the future, this function runs,
  // but it's too late
  newDeals = deals;
});

// (2) this is called immediately, `newDeals` is an empty array
this.setState({ deals: newDeals });

디버거를 사용하여 스크립트를 일시 정지하면 콜백을 호출할 수 있는 내선 시간이 주어집니다.계속 진행하면 데이터가 도착하여 정상적으로 동작하는 것처럼 보입니다.

수정하려면 , 다음의 작업을 실시합니다.setState데이터가 Chrome 내선번호에서 돌아온 후 호출:

var newDeals = [];

// (1) first chrome.runtime.sendMessage is called, and *registers a callback*
// so that when the data comes back *in the future*
// the function will be called
chrome.runtime.sendMessage({...}, function(deals) {
  // (2) sometime in the future, this function runs
  newDeals = deals;

  // (3) now you can call `setState` with the data
  this.setState({ deals: newDeals });
}.bind(this)); // Don't forget to bind(this) (or use an arrow function)

[편집]

이 방법으로 문제가 해결되지 않으면 이 질문에 대한 다른 답변을 확인하십시오. 이 답변은 구성 요소가 업데이트되지 않을 수 있는 다른 이유를 설명합니다.

또 하나의 아주 쉬운 실수가 문제의 근원이었습니다.내가 직접 썼어shouldComponentUpdate방법.

상태를 올바르게 업데이트하려면 어레이를 변환하지 마십시오.배열 복사본을 생성한 다음 복사된 배열의 상태를 설정해야 합니다.

const [deals, setDeals] = useState([]);
    
   function updateDeals(deal) {
      const newDeals = [...deals]; // spreading operator which doesn't mutate the array and returns new array
      newDeals.push(deal);

      // const newDeals = deals.concat(deal); // concat merges the passed value to the array and return a new array
      // const newDeals = [...deals, deal] // directly passing the new value and we don't need to use push
    
      setDeals(newDeals);
    }

경우에는 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★.this.setState({})맞긴 맞는데 제 기능이 여기에 얽매이지 않아서 안 되더라고요." " " .bind(this) 콜 콜의 실행this.foo = this.foo.bind(this)정했습습니니다

나의 문제는 'React'를 사용한다는 것이었다.'React'를 사용해야 할 때 PureComponent'를 선택합니다.컴포넌트'입니다.

업데이트 중이고, 리듀서에 전달된 동일한 오브젝트를 반품하고 있습니다.이렇게 상태 객체를 반환하기 직전에 요소를 복사하여 수정했습니다.

Object.assign({}, state)

React-Native에서도 API 응답과 거부 상태가 갱신되지 않는 문제를 겪고 있었습니다.

apiCall().then(function(resp) { this.setState({data: resp}) // wasn't updating }

는 문제를 했다.function

apiCall().then((resp) => {
    this.setState({data: resp}) // rendering the view as expected
}

을 사용법하면 화살표 되었습니다.this은 항상

많은 답변(대부분의 답변은 시나리오에 맞는 답변)을 검토했지만, 어느 답변도 문제를 해결하지 못한 후, 저는 제 사례가 조금 다르다는 것을 깨달았습니다.

이상한 시나리오에서는 컴포넌트가 주(州) 내에서 렌더링되고 있었기 때문에 업데이트할 수 없었습니다.다음은 간단한 예입니다.

constructor() {
    this.myMethod = this.myMethod.bind(this);
    this.changeTitle = this.changeTitle.bind(this);

    this.myMethod();
}

changeTitle() {
    this.setState({title: 'I will never get updated!!'});
}

myMethod() {
    this.setState({body: <div>{this.state.title}</div>});
}

render() {
    return <>
        {this.state.body}
        <Button onclick={() => this.changeTitle()}>Change Title!</Button>
    </>
}

바디를 상태로부터 렌더링하지 않도록 코드를 리팩터링한 후 정상적으로 동작:)

비슷한 문제를 안고 있지만 컴포넌트를 클래스화하고 리액트 리덕터를 사용하는 경우 --> api 콜을 리덕터 외부로 이동합니다.리듀서는 api 호출을 실행해서는 안 됩니다.자세한 대응은 https://stackoverflow.com/a/39516485/12121297 를 참조해 주세요.

언급URL : https://stackoverflow.com/questions/25937369/react-component-not-re-rendering-on-state-change

반응형