Рекомендации для MobX form не обновлять пользовательский интерфейс напрямую вне формы

#reactjs #mobx #mobx-react

#reactjs #mobx #mobx-реагировать

Вопрос:

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

Каков наилучший метод в mobx, позволяющий использовать форму, использующую хранилище для управления состоянием, при этом не обновляя значения в этом выпадающем виджете при вводе?

Прямо сейчас у меня просто есть отдельные объекты в моем магазине: profileFormValues и userData, и я использую profileFormValues для формы и обновляю profile и userData, чтобы отобразить их в другом месте приложения. Когда обновление выполнено успешно, оно присваивает userData значение profileFormValues . Это выглядит неаккуратно, и я надеюсь, что есть какой-то способ сделать это более чисто и сохранить единственный источник истины пользовательских данных

Об этом почти наверняка спрашивали, но я не могу понять, как указать название, чтобы знать наверняка

Ответ №1:

ViewModel из mobx-utils пакета будет хорошо соответствовать вашему варианту использования.

Пример

 const { useState } = React;
const { observable } = mobx;
const { observer } = mobxReactLite;
const { createViewModel } = mobxUtils;

const state = observable({
  email: "foo@bar.com",
  name: "baz"
});

const App = observer(() => {
  const [viewState] = useState(() => createViewModel(state));

  return (
    <div>
      <h1>Global state:</h1>
      <div>{JSON.stringify(state)}</div>
      <h2>View state:</h2>
      <div>{JSON.stringify(viewState)}</div>
      <form
        onSubmit={(e) => {
          e.preventDefault();
          viewState.submit();
        }}
      >
        <input
          value={viewState.email}
          onChange={(e) => viewState.email = e.target.value}
        />
        <input
          value={viewState.name}
          onChange={(e) => viewState.name = e.target.value}
        />
        <button>Submit</button>
      </form>
    </div>
  );
});

ReactDOM.render(<App />, document.getElementById("root")); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/mobx@6.0.4/dist/mobx.umd.production.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/mobx-react-lite@3.1.6/dist/mobxreactlite.umd.production.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/mobx-utils@6.0.3/mobx-utils.umd.min.js"></script>

<div id="root"></div>