Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 1 addition & 26 deletions scripts/fiber/tests-failing.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@ src/addons/transitions/__tests__/ReactCSSTransitionGroup-test.js
* should transition from false to one

src/isomorphic/classic/__tests__/ReactContextValidator-test.js
* should filter out context not in contextTypes
* should filter context properly in callbacks
* should pass previous context to lifecycles
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a new PR I extracted from "should filter context properly in callbacks". It covers the componentDidUpdate with nextContext which we punted on.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🙄 I meant test, not PR


src/isomorphic/classic/class/__tests__/ReactBind-test.js
* Holds reference to instance
Expand All @@ -31,24 +30,9 @@ src/isomorphic/classic/class/__tests__/ReactBindOptout-test.js
* works with mixins that have not opted out of autobinding
* works with mixins that have opted out of autobinding

src/isomorphic/classic/class/__tests__/ReactClass-test.js
* renders based on context getInitialState

src/isomorphic/classic/element/__tests__/ReactElementValidator-test.js
* includes the owner name when passing null, undefined, boolean, or number

src/isomorphic/modern/class/__tests__/ReactCoffeeScriptClass-test.coffee
* renders based on context in the constructor
* supports this.context passed via getChildContext

src/isomorphic/modern/class/__tests__/ReactES6Class-test.js
* renders based on context in the constructor
* supports this.context passed via getChildContext

src/isomorphic/modern/class/__tests__/ReactTypeScriptClass-test.ts
* renders based on context in the constructor
* supports this.context passed via getChildContext

src/isomorphic/modern/element/__tests__/ReactJSXElementValidator-test.js
* should give context for PropType errors in nested components.

Expand Down Expand Up @@ -441,13 +425,6 @@ src/renderers/shared/stack/reconciler/__tests__/ReactCompositeComponent-test.js
* should warn about `setState` on unmounted components
* should warn about `setState` in render
* should warn about `setState` in getChildContext
* should pass context to children when not owner
* should pass context when re-rendered for static child
* should pass context when re-rendered for static child within a composite component
* should pass context transitively
* should pass context when re-rendered
* unmasked context propagates through updates
* should trigger componentWillReceiveProps for context changes
* should update refs if shouldComponentUpdate gives false
* should support objects with prototypes as state

Expand All @@ -467,10 +444,8 @@ src/renderers/shared/stack/reconciler/__tests__/ReactMultiChildText-test.js
* should throw if rendering both HTML and children

src/renderers/shared/stack/reconciler/__tests__/ReactStatelessComponent-test.js
* should pass context thru stateless component
* should warn when stateless component returns array
* should throw on string refs in pure functions
* should receive context
* should warn when using non-React functions in JSX

src/renderers/shared/stack/reconciler/__tests__/ReactUpdates-test.js
Expand Down
3 changes: 0 additions & 3 deletions scripts/fiber/tests-passing-except-dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,6 @@ src/isomorphic/classic/element/__tests__/ReactElementValidator-test.js
* warns for keys with component stack info
* should give context for PropType errors in nested components.

src/isomorphic/modern/element/__tests__/ReactJSXElementValidator-test.js
* should warn on invalid context types

src/renderers/dom/shared/__tests__/CSSPropertyOperations-test.js
* should warn when using hyphenated style names
* should warn when updating hyphenated style names
Expand Down
26 changes: 26 additions & 0 deletions scripts/fiber/tests-passing.txt
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,10 @@ src/isomorphic/children/__tests__/sliceChildren-test.js
* should allow static children to be sliced
* should slice nested children

src/isomorphic/classic/__tests__/ReactContextValidator-test.js
* should filter out context not in contextTypes
* should pass next context to lifecycles

src/isomorphic/classic/class/__tests__/ReactBind-test.js
* warns if you try to bind to this
* does not warn if you pass an auto-bound method to setState
Expand All @@ -149,6 +153,7 @@ src/isomorphic/classic/class/__tests__/ReactClass-test.js
* should throw if a reserved property is in statics
* should support statics
* should work with object getInitialState() return values
* renders based on context getInitialState
* should throw with non-object getInitialState() return values
* should work with a null getInitialState() return value
* should throw when using legacy factories
Expand Down Expand Up @@ -354,6 +359,7 @@ src/isomorphic/modern/class/__tests__/ReactCoffeeScriptClass-test.coffee
* renders a simple stateless component with prop
* renders based on state using initial values in this.props
* renders based on state using props in the constructor
* renders based on context in the constructor
* renders only once when setting state in componentWillMount
* should throw with non-object in the initial state property
* should render with null in the initial state property
Expand All @@ -365,6 +371,7 @@ src/isomorphic/modern/class/__tests__/ReactCoffeeScriptClass-test.coffee
* should warn when misspelling shouldComponentUpdate
* should warn when misspelling componentWillReceiveProps
* should throw AND warn when trying to access classic APIs
* supports this.context passed via getChildContext
* supports classic refs
* supports drilling through to the DOM using findDOMNode

Expand All @@ -374,6 +381,7 @@ src/isomorphic/modern/class/__tests__/ReactES6Class-test.js
* renders a simple stateless component with prop
* renders based on state using initial values in this.props
* renders based on state using props in the constructor
* renders based on context in the constructor
* renders only once when setting state in componentWillMount
* should throw with non-object in the initial state property
* should render with null in the initial state property
Expand All @@ -385,6 +393,7 @@ src/isomorphic/modern/class/__tests__/ReactES6Class-test.js
* should warn when misspelling shouldComponentUpdate
* should warn when misspelling componentWillReceiveProps
* should throw AND warn when trying to access classic APIs
* supports this.context passed via getChildContext
* supports classic refs
* supports drilling through to the DOM using findDOMNode

Expand All @@ -399,6 +408,7 @@ src/isomorphic/modern/class/__tests__/ReactTypeScriptClass-test.ts
* renders a simple stateless component with prop
* renders based on state using initial values in this.props
* renders based on state using props in the constructor
* renders based on context in the constructor
* renders only once when setting state in componentWillMount
* should throw with non-object in the initial state property
* should render with null in the initial state property
Expand All @@ -410,6 +420,7 @@ src/isomorphic/modern/class/__tests__/ReactTypeScriptClass-test.ts
* should warn when misspelling shouldComponentUpdate
* should warn when misspelling componentWillReceiveProps
* should throw AND warn when trying to access classic APIs
* supports this.context passed via getChildContext
* supports classic refs
* supports drilling through to the DOM using findDOMNode

Expand Down Expand Up @@ -446,6 +457,7 @@ src/isomorphic/modern/element/__tests__/ReactJSXElementValidator-test.js
* should not check the default for explicit null
* should check declared prop types
* should warn on invalid prop types
* should warn on invalid context types
* should warn if getDefaultProps is specificed on the class

src/renderers/dom/__tests__/ReactDOMProduction-test.js
Expand Down Expand Up @@ -806,6 +818,11 @@ src/renderers/shared/fiber/__tests__/ReactIncremental-test.js
* performs batched updates at the end of the batch
* can nest batchedUpdates
* can handle if setState callback throws
* merges and masks context
* does not leak own context into context provider
* provides context when reusing work
* reads context when setState is below the provider
* reads context when setState is above the provider

src/renderers/shared/fiber/__tests__/ReactIncrementalErrorHandling-test.js
* catches render error in a boundary during mounting
Expand Down Expand Up @@ -1018,7 +1035,14 @@ src/renderers/shared/stack/reconciler/__tests__/ReactCompositeComponent-test.js
* should call componentWillUnmount before unmounting
* should warn when shouldComponentUpdate() returns undefined
* should warn when componentDidUnmount method is defined
* should pass context to children when not owner
* should skip update when rerendering element in container
* should pass context when re-rendered for static child
* should pass context when re-rendered for static child within a composite component
* should pass context transitively
* should pass context when re-rendered
* unmasked context propagates through updates
* should trigger componentWillReceiveProps for context changes
* only renders once if updated in componentWillReceiveProps
* should allow access to findDOMNode in componentWillUnmount
* context should be passed down from the parent
Expand Down Expand Up @@ -1147,9 +1171,11 @@ src/renderers/shared/stack/reconciler/__tests__/ReactStatelessComponent-test.js
* should render stateless component
* should update stateless component
* should unmount stateless component
* should pass context thru stateless component
* should provide a null ref
* should use correct name in key warning
* should support default props and prop types
* should receive context
* should work with arrow functions
* should allow simple functions to return null
* should allow simple functions to return false
Expand Down
45 changes: 40 additions & 5 deletions src/isomorphic/classic/__tests__/ReactContextValidator-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,10 @@ describe('ReactContextValidator', () => {
expect(instance.refs.child.context).toEqual({foo: 'abc'});
});

it('should filter context properly in callbacks', () => {
it('should pass next context to lifecycles', () => {
var actualComponentWillReceiveProps;
var actualShouldComponentUpdate;
var actualComponentWillUpdate;
var actualComponentDidUpdate;

var Parent = React.createClass({
childContextTypes: {
Expand Down Expand Up @@ -113,6 +112,45 @@ describe('ReactContextValidator', () => {
actualComponentWillUpdate = nextContext;
},

render: function() {
return <div />;
},
});

var container = document.createElement('div');
ReactDOM.render(<Parent foo="abc" />, container);
ReactDOM.render(<Parent foo="def" />, container);
expect(actualComponentWillReceiveProps).toEqual({foo: 'def'});
expect(actualShouldComponentUpdate).toEqual({foo: 'def'});
expect(actualComponentWillUpdate).toEqual({foo: 'def'});
});

it('should pass previous context to lifecycles', () => {
var actualComponentDidUpdate;

var Parent = React.createClass({
childContextTypes: {
foo: React.PropTypes.string.isRequired,
bar: React.PropTypes.string.isRequired,
},

getChildContext: function() {
return {
foo: this.props.foo,
bar: 'bar',
};
},

render: function() {
return <Component />;
},
});

var Component = React.createClass({
contextTypes: {
foo: React.PropTypes.string,
},

componentDidUpdate: function(prevProps, prevState, prevContext) {
actualComponentDidUpdate = prevContext;
},
Expand All @@ -125,9 +163,6 @@ describe('ReactContextValidator', () => {
var container = document.createElement('div');
ReactDOM.render(<Parent foo="abc" />, container);
ReactDOM.render(<Parent foo="def" />, container);
expect(actualComponentWillReceiveProps).toEqual({foo: 'def'});
expect(actualShouldComponentUpdate).toEqual({foo: 'def'});
expect(actualComponentWillUpdate).toEqual({foo: 'def'});
expect(actualComponentDidUpdate).toEqual({foo: 'abc'});
});

Expand Down
35 changes: 30 additions & 5 deletions src/renderers/shared/fiber/ReactFiberBeginWork.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,15 @@ var {
reconcileChildFibersInPlace,
cloneChildFibers,
} = require('ReactChildFiber');

var ReactTypeOfWork = require('ReactTypeOfWork');
var {
getMaskedContext,
isContextProvider,
hasContextChanged,
pushContextProvider,
resetContext,
} = require('ReactFiberContext');
var {
IndeterminateComponent,
FunctionalComponent,
Expand Down Expand Up @@ -144,6 +152,7 @@ module.exports = function<T, P, I, TI, C>(
function updateFunctionalComponent(current, workInProgress) {
var fn = workInProgress.type;
var props = workInProgress.pendingProps;
var context = getMaskedContext(workInProgress);

// TODO: Disable this before release, since it is not part of the public API
// I use this for testing to compare the relative overhead of classes.
Expand All @@ -159,9 +168,9 @@ module.exports = function<T, P, I, TI, C>(

if (__DEV__) {
ReactCurrentOwner.current = workInProgress;
nextChildren = fn(props);
nextChildren = fn(props, context);
} else {
nextChildren = fn(props);
nextChildren = fn(props, context);
}
reconcileChildren(current, workInProgress, nextChildren);
return workInProgress.child;
Expand Down Expand Up @@ -190,6 +199,10 @@ module.exports = function<T, P, I, TI, C>(
ReactCurrentOwner.current = workInProgress;
const nextChildren = instance.render();
reconcileChildren(current, workInProgress, nextChildren);
// Put context on the stack because we will work on children
if (isContextProvider(workInProgress)) {
pushContextProvider(workInProgress, true);
}
return workInProgress.child;
}

Expand Down Expand Up @@ -249,13 +262,15 @@ module.exports = function<T, P, I, TI, C>(
}
var fn = workInProgress.type;
var props = workInProgress.pendingProps;
var context = getMaskedContext(workInProgress);

var value;

if (__DEV__) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what the reason of such style?
why here you can't just have

    var value = fn(props, context);

    if (__DEV__) {
      ReactCurrentOwner.current = workInProgress;
    }

or

    if (__DEV__) {
      ReactCurrentOwner.current = workInProgress;
    }
    var value = fn(props, context);

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think there's any reason for this, putting just current owner assignment in a condition would be equivalent.

ReactCurrentOwner.current = workInProgress;
value = fn(props);
value = fn(props, context);
} else {
value = fn(props);
value = fn(props, context);
}

if (typeof value === 'object' && value && typeof value.render === 'function') {
Expand Down Expand Up @@ -345,6 +360,10 @@ module.exports = function<T, P, I, TI, C>(

cloneChildFibers(current, workInProgress);
markChildAsProgressed(current, workInProgress, priorityLevel);
// Put context on the stack because we will work on children
if (isContextProvider(workInProgress)) {
pushContextProvider(workInProgress, false);
}
return workInProgress.child;
}

Expand All @@ -355,6 +374,11 @@ module.exports = function<T, P, I, TI, C>(
}

function beginWork(current : ?Fiber, workInProgress : Fiber, priorityLevel : PriorityLevel) : ?Fiber {
if (!workInProgress.return) {
// Don't start new work with context on the stack.
resetContext();
}

if (workInProgress.pendingWorkPriority === NoWork ||
workInProgress.pendingWorkPriority > priorityLevel) {
return bailoutOnLowPriority(current, workInProgress);
Expand All @@ -375,7 +399,8 @@ module.exports = function<T, P, I, TI, C>(
workInProgress.memoizedProps !== null &&
workInProgress.pendingProps === workInProgress.memoizedProps
)) &&
workInProgress.updateQueue === null) {
workInProgress.updateQueue === null &&
!hasContextChanged()) {
return bailoutOnAlreadyFinishedWork(current, workInProgress);
}

Expand Down
Loading