Почему в MobX плохие побочные эффекты в функциях рендеринга - PullRequest
1 голос
/ 18 июня 2020

Недавно меня спросили:

Почему я не могу писать в состояние mobx в функции рендеринга

Я знаю, что Mobx запрещает это, но это не так хорошо, однако я также знаю, что вы можете обойти проверку Mobx, просто немного подождав, например: Promise.resolve().then(() => observable.value = "test").

У меня был плохой опыт отладки кода в других фреймворках, когда программисты вызывали побочные эффекты в функциональном функции (функции, подобные рендерингу). Однако большая часть моих неудачных опытов связана с действительно сложными ошибками, которые я до сих пор не совсем понимаю, поэтому я не мог придумать простого объяснения, почему это плохо.

* 1011 ответьте и просто сказал другому программисту:

Это плохо, просто поверьте мне, не пытайтесь это делать, это вызовет проблемы позже

Какой лучший ответ на вопрос «почему я не могу записать в состояние mobx в функции рендеринга»?


ПРИМЕЧАНИЯ:

Меня особенно интересуют любые конкретные примеры кода, который может (неожиданно) выйти из строя.

Я создал пример кода, который изменяет состояние Mobx в функциях рендеринга. Каждый компонент устанавливает глобальное состояние curPageName.value при визуализации и отображает эту переменную, а другой компонент также отображает эту переменную. Это довольно устрашающе, но технически работает: https://codesandbox.io/s/mobx-playground-u8per?file= / src / index. js

import React from "react";
import ReactDOM from "react-dom";

import { observable } from "mobx";
import { observer } from "mobx-react";

let curPageName = observable({
  value: "test"
});

const Test = observer(() => {
  Promise.resolve().then(() => (curPageName.value = "Test"));
  return <div>{curPageName.value}</div>;
});
const Test2 = observer(() => {
  Promise.resolve().then(() => (curPageName.value = "Test2"));
  return <div>{curPageName.value}</div>;
});

@observer
class MainPage extends React.Component {
  state = {
    page: Test
  };
  render() {
    let Page = this.state.page;
    return (
      <React.Fragment>
        <div>Cur Page: {curPageName.value}</div>
        <div>
          <button onClick={() => this.setState({ page: Test })}>Test</button>
        </div>
        <div>
          <button onClick={() => this.setState({ page: Test2 })}>Test2</button>
        </div>
        <Page />
      </React.Fragment>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<MainPage />, rootElement);
...