Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Warn when second argument is passed to useContext #14729

Merged
merged 1 commit into from Jan 31, 2019
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -613,8 +613,114 @@ describe('ReactDOMServerHooks', () => {
});

describe('useContext', () => {
itThrowsWhenRendering(
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The diff confused git. This is not a new test.

All I did is move the useContext() test with bits into readContext() section below.

'if used inside a class component',
async render => {
const Context = React.createContext({}, () => {});
class Counter extends React.Component {
render() {
let [count] = useContext(Context);
return <Text text={count} />;
}
}

return render(<Counter />);
},
'Hooks can only be called inside the body of a function component.',
);
});

itRenders(
'can use the same context multiple times in the same function',
async render => {
const Context = React.createContext({foo: 0, bar: 0, baz: 0});

function Provider(props) {
return (
<Context.Provider
value={{foo: props.foo, bar: props.bar, baz: props.baz}}>
{props.children}
</Context.Provider>
);
}

function FooAndBar() {
const {foo} = useContext(Context);
const {bar} = useContext(Context);
return <Text text={`Foo: ${foo}, Bar: ${bar}`} />;
}

function Baz() {
const {baz} = useContext(Context);
return <Text text={'Baz: ' + baz} />;
}

class Indirection extends React.Component {
render() {
return this.props.children;
}
}

function App(props) {
return (
<div>
<Provider foo={props.foo} bar={props.bar} baz={props.baz}>
<Indirection>
<Indirection>
<FooAndBar />
</Indirection>
<Indirection>
<Baz />
</Indirection>
</Indirection>
</Provider>
</div>
);
}

const domNode = await render(<App foo={1} bar={3} baz={5} />);
expect(clearYields()).toEqual(['Foo: 1, Bar: 3', 'Baz: 5']);
expect(domNode.childNodes.length).toBe(2);
expect(domNode.firstChild.tagName).toEqual('SPAN');
expect(domNode.firstChild.textContent).toEqual('Foo: 1, Bar: 3');
expect(domNode.lastChild.tagName).toEqual('SPAN');
expect(domNode.lastChild.textContent).toEqual('Baz: 5');
},
);

itRenders('warns when bitmask is passed to useContext', async render => {
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 test.

let Context = React.createContext('Hi');

function Foo() {
return <span>{useContext(Context, 1)}</span>;
}

const domNode = await render(<Foo />, 1);
expect(domNode.textContent).toBe('Hi');
});

describe('useDebugValue', () => {
itRenders('is a noop', async render => {
function Counter(props) {
const debugValue = useDebugValue(123);
return <Text text={typeof debugValue} />;
}

const domNode = await render(<Counter />);
expect(domNode.textContent).toEqual('undefined');
});
});

describe('readContext', () => {
function readContext(Context, observedBits) {
const dispatcher =
React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED
.ReactCurrentDispatcher.current;
return dispatcher.readContext(Context, observedBits);
}

itRenders(
'can use the same context multiple times in the same function',
'can read the same context multiple times in the same function',
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 existing test which I made use readContext instead.

async render => {
const Context = React.createContext(
{foo: 0, bar: 0, baz: 0},
Expand Down Expand Up @@ -643,13 +749,13 @@ describe('ReactDOMServerHooks', () => {
}

function FooAndBar() {
const {foo} = useContext(Context, 0b001);
const {bar} = useContext(Context, 0b010);
const {foo} = readContext(Context, 0b001);
const {bar} = readContext(Context, 0b010);
return <Text text={`Foo: ${foo}, Bar: ${bar}`} />;
}

function Baz() {
const {baz} = useContext(Context, 0b100);
const {baz} = readContext(Context, 0b100);
return <Text text={'Baz: ' + baz} />;
}

Expand Down Expand Up @@ -689,43 +795,6 @@ describe('ReactDOMServerHooks', () => {
},
);

itThrowsWhenRendering(
'if used inside a class component',
async render => {
const Context = React.createContext({}, () => {});
class Counter extends React.Component {
render() {
let [count] = useContext(Context);
return <Text text={count} />;
}
}

return render(<Counter />);
},
'Hooks can only be called inside the body of a function component.',
);
});

describe('useDebugValue', () => {
itRenders('is a noop', async render => {
function Counter(props) {
const debugValue = useDebugValue(123);
return <Text text={typeof debugValue} />;
}

const domNode = await render(<Counter />);
expect(domNode.textContent).toEqual('undefined');
});
});

describe('readContext', () => {
function readContext(Context, observedBits) {
const dispatcher =
React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED
.ReactCurrentDispatcher.current;
return dispatcher.readContext(Context, observedBits);
}

itRenders('with a warning inside useMemo and useReducer', async render => {
const Context = React.createContext(42);

Expand Down