Skip to content

Commit

Permalink
feat(weapp): 从prevProps改为使用nextProps,避免props的提前赋值
Browse files Browse the repository at this point in the history
  • Loading branch information
huey-LS authored and Chen-jj committed Nov 12, 2019
1 parent 5e8c828 commit b2bdb6e
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 11 deletions.
2 changes: 1 addition & 1 deletion packages/taro-weapp/src/create-component.js
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
20 changes: 11 additions & 9 deletions packages/taro-weapp/src/lifecycle.js
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Expand All @@ -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
Expand All @@ -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
}

Expand All @@ -114,7 +117,6 @@ export function mountComponent (component) {
}
}
doUpdate(component, props, component.state)
component.prevProps = component.props
component.prevState = component.state
}

Expand Down
4 changes: 3 additions & 1 deletion packages/taro-weapp/src/propsManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit b2bdb6e

Please sign in to comment.