diff --git a/packages/taro-weapp/src/create-component.js b/packages/taro-weapp/src/create-component.js index f1f24e1e75e0..542d094864fc 100644 --- a/packages/taro-weapp/src/create-component.js +++ b/packages/taro-weapp/src/create-component.js @@ -58,7 +58,7 @@ function bindProperties (weappComponentConf, ComponentClass, isPage) { if (!this.$component || !this.$component.__isReady) return const nextProps = filterProps(ComponentClass.defaultProps, {}, this.$component.props, this.data.extraProps) - this.$component.props = nextProps + this.$component.nextProps = nextProps nextTick(() => { this.$component._unsafeCallUpdate = true updateComponent(this.$component) diff --git a/packages/taro-weapp/src/lifecycle.js b/packages/taro-weapp/src/lifecycle.js index 2e562782be35..68e36e49c997 100644 --- a/packages/taro-weapp/src/lifecycle.js +++ b/packages/taro-weapp/src/lifecycle.js @@ -44,6 +44,10 @@ function callGetSnapshotBeforeUpdate (component, props, state) { export function updateComponent (component) { const { props, __propTypes } = component + // 由 forceUpdate 或者组件自身 setState 发起的 update 可能是没有新的nextProps的 + const nextProps = component.nextProps || props + const prevProps = props + if (isDEV && __propTypes) { let componentName = component.constructor.name if (isUndefined(componentName)) { @@ -52,18 +56,17 @@ export function updateComponent (component) { } PropTypes.checkPropTypes(__propTypes, props, 'prop', componentName) } - const prevProps = component.prevProps || props - component.props = prevProps + if (component.__mounted && component._unsafeCallUpdate === true && !hasNewLifecycle(component) && component.componentWillReceiveProps) { component._disable = true - component.componentWillReceiveProps(props) + component.componentWillReceiveProps(nextProps) component._disable = false } let state = component.getState() const prevState = component.prevState || state - const stateFromProps = callGetDerivedStateFromProps(component, props, state) + const stateFromProps = callGetDerivedStateFromProps(component, nextProps, state) if (!isUndefined(stateFromProps)) { state = stateFromProps @@ -73,21 +76,21 @@ export function updateComponent (component) { if (component.__mounted) { if (typeof component.shouldComponentUpdate === 'function' && !component._isForceUpdate && - component.shouldComponentUpdate(props, state) === false) { + component.shouldComponentUpdate(nextProps, state) === false) { skip = true } else if (!hasNewLifecycle(component) && isFunction(component.componentWillUpdate)) { - component.componentWillUpdate(props, state) + component.componentWillUpdate(nextProps, state) } } - component.props = props + component.props = nextProps component.state = state component._dirty = false component._isForceUpdate = false if (!skip) { doUpdate(component, prevProps, prevState) } - component.prevProps = component.props + delete component.nextProps component.prevState = component.state } @@ -114,7 +117,6 @@ export function mountComponent (component) { } } doUpdate(component, props, component.state) - component.prevProps = component.props component.prevState = component.state } diff --git a/packages/taro-weapp/src/propsManager.js b/packages/taro-weapp/src/propsManager.js index 334617fd47f0..0294913d5405 100644 --- a/packages/taro-weapp/src/propsManager.js +++ b/packages/taro-weapp/src/propsManager.js @@ -30,7 +30,9 @@ class Manager { const extraProps = (component.$scope && component.$scope.data && component.$scope.data.extraProps) || null const nextProps = filterProps(ComponentClass.defaultProps, props, component.props, extraProps) - component.props = nextProps + // 这里原来是提前修改了 props, 实际更新又是nextTick异步的,这样可以会导致很多问题 + // 很难保证如果开发者无意中多次并发更新,props可能提前于生命周期被获取到 + component.nextProps = nextProps nextTick(() => { component._unsafeCallUpdate = true updateComponent(component)