首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >this.props.prop和nextProps.prop与mobx的比较

this.props.prop和nextProps.prop与mobx的比较
EN

Stack Overflow用户
提问于 2016-05-12 11:44:30
回答 3查看 1.8K关注 0票数 1

有办法用mobx做这样的事吗?

代码语言:javascript
复制
componentWillUpdate(nextProps) {
  if (this.props.prop !== nextProps.prop) {
    /* side effect, ex. router transition */
  }
}

根据我的经验,this.props.prop总是和nextProps.prop一样,即使在componentWill-的钩子里.

UPD这里是更具体的用例-简单登录场景:

商店

代码语言:javascript
复制
class AppStore {
  @observable viewer = new ViewerStore();
}

class ViewerStore {
  @observable id;
  @observable name;
  @observable error;

  fromJSON(json = {}) {
    this.id = json.id;
    this.name = json.name;
  }

  clearError() {
    this.error = null;
  }

  login({ email, password }) {
    fetch('/login', {
      method: 'POST',
      body: JSON.stringify({
        email,
        password
      }),
      credentials: 'same-origin'
    })
    .then(json => {
      this.fromJSON(json);
    })
    .catch(({ error }) => {
      this.error = error;
    })
  }
}

反应部件

代码语言:javascript
复制
class LogInPage extends Component {
  componentWillUpdate(nextProps) {
    if (nextProps.viewer.id && !this.props.viewer.id) {
      this.props.viewer.clearError();
      this.props.onSuccess();
    }
  }

  login = e => {
    e.preventDefault();
    this.props.viewer.login({
      email: e.target.elements['email'].value,
      password: e.target.elements['password'].value,
    });
  }

  render() {
    return (
      <div>
        <h1>Log In</h1>
        <form onSuccess={this.login}>
          <input type="text" name="email" />
          <input type="password" name="password" />
          <input type="submit" />
        </form>
        { this.props.viewer.error && (
          <div>
            <b>Error</b>: {this.props.viewer.error}
          </div>
        )}
      </div>
    );
  }
}

const store = new AppStore();
ReactDOM.render(<LogInPage 
  viewer={store.viewer}
  onSuccess={() => alert("Hello!")}  
 />
, container);

基本上,当查看器idundefined切换到某物时,我只想做一些事情

EN

回答 3

Stack Overflow用户

发布于 2016-05-12 17:59:44

谢谢你的更新,这就澄清了很多问题。这在一定程度上取决于您想要做什么,但是如果您想要更改组件的呈现,就足以从@observer包中用mobx-react来装饰您的组件。然后,当商店更改时,它将自动重新呈现。

如果要执行任何其他操作,可以在componentWillMount中设置自动运行。喜欢

代码语言:javascript
复制
componentWillMount() {
    this.autorunDisposer = mobx.autorun(() => {
        if (nextProps.viewer.id && !this.props.viewer.id) {
            this.props.viewer.clearError();
            this.props.onSuccess();
        }
    })
}

但我并不经常看到这种模式,因为在你的商店里有这样的逻辑往往更干净。就我个人而言,我希望登录表单组件看起来像这样:

代码语言:javascript
复制
@observer class RequiresLogin extends Component {
    render() {
        if (this.props.viewerStore.id !== undefined) {
            return this.props.children
        } else {
            return <LoginPage viewer={this.props.viewerStore}/>
        }
    }
}

@observer class MyTestPage extends Component {
    render() {
        return <RequiresLogin viewer={this.props.viewerStore}>
            Secret Area!
        </RequiresLogin>
    }
}

@observer class LogInPage extends Component {
  login = e => {
    e.preventDefault();
    this.props.viewer.login({
      // tip: use React refs or the onChange handler to update local state:
      email: e.target.elements['email'].value,
      password: e.target.elements['password'].value,
    });
  }

  render() {
    if (this.props.viewer.id)
        return null; // no need to show login form
    return (
      <div>
        <h1>Log In</h1>
        <form onSuccess={this.login}>
          <input type="text" name="email" />
          <input type="password" name="password" />
          <input type="submit" />
        </form>
        { this.props.viewer.error && (
          <div>
            <b>Error</b>: {this.props.viewer.error}
          </div>
        )}
      </div>
    );
  }
}
票数 2
EN

Stack Overflow用户

发布于 2016-05-12 14:10:56

在99%的情况下,发生这种情况是因为代码道具中的其他地方是直接变异的。这是不允许的反应。

典型场景包括:

代码语言:javascript
复制
var myObject = this.props.someObject;  // myObject is a POINTER to props, not copy
myObject.attribute = newAttribute;     // Now props are directly mutated

var myArray = this.props.someArray;
myArray.splice(a,b);                   // splice directly mutates array

若要解决此问题,请在更新道具之前创建道具对象的适当副本。

票数 1
EN

Stack Overflow用户

发布于 2016-05-12 16:23:29

实际上,问题的发生是因为我将一个mobx存储作为单一的支柱(为了调用它的方法,比如this.props.store.update()),所以即使在存储中发生了一些变化,组件被mobx更新了,nextProps仍然保持着对该存储的相同引用。

最后,当我需要这样的检查时,我终于把商店破坏成了组件的道具。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37185889

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档