Skip to content

Commit dd3e5d9

Browse files
authored
Merge pull request #1214 from aberezkin/consuming-defined-values
Pass defined falsy values in consumers' children in replacement render
2 parents a058148 + d29ba0b commit dd3e5d9

File tree

2 files changed

+179
-2
lines changed

2 files changed

+179
-2
lines changed

src/reconciler/hotReplacementRender.js

+4-2
Original file line numberDiff line numberDiff line change
@@ -287,10 +287,12 @@ const hotReplacementRender = (instance, stack) => {
287287
next(stackChild.instance)
288288
} else if (isContextConsumer(child)) {
289289
try {
290+
const contextValue = stackContext().get(getContextProvider(childType))
290291
next({
291292
children: (child.props ? child.props.children : child.children[0])(
292-
stackContext().get(getContextProvider(childType)) ||
293-
childType[CONTEXT_CURRENT_VALUE],
293+
contextValue !== undefined
294+
? contextValue
295+
: childType[CONTEXT_CURRENT_VALUE],
294296
),
295297
})
296298
} catch (e) {

test/AppContainer.dev.test.js

+175
Original file line numberDiff line numberDiff line change
@@ -1040,6 +1040,181 @@ describe(`AppContainer (dev)`, () => {
10401040
expect(wrapper.text()).toBe('new render + old state')
10411041
},
10421042
)
1043+
1044+
it('passes a default context value', () => {
1045+
if (React.version.startsWith('16')) {
1046+
const spy = jest.fn()
1047+
const contextValue = 'value'
1048+
const { Consumer } = React.createContext('value')
1049+
1050+
class App extends Component {
1051+
render() {
1052+
return (
1053+
<Consumer>
1054+
{value => {
1055+
spy()
1056+
return <div>{value}</div>
1057+
}}
1058+
</Consumer>
1059+
)
1060+
}
1061+
}
1062+
1063+
RHL.register(App, 'App', 'test.js')
1064+
1065+
const wrapper = mount(
1066+
<AppContainer>
1067+
<App />
1068+
</AppContainer>,
1069+
)
1070+
1071+
expect(wrapper.contains(<div>{contextValue}</div>)).toBe(true)
1072+
expect(spy).toHaveBeenCalledTimes(1)
1073+
} else {
1074+
expect(true).toBe(true)
1075+
}
1076+
})
1077+
1078+
it('passes provider defined context value', () => {
1079+
if (React.version.startsWith('16')) {
1080+
const spy = jest.fn()
1081+
const contextValue = 'value'
1082+
const { Provider, Consumer } = React.createContext()
1083+
1084+
class App extends Component {
1085+
render() {
1086+
return (
1087+
<Provider value={contextValue}>
1088+
<Consumer>
1089+
{value => {
1090+
spy()
1091+
return <div>{value}</div>
1092+
}}
1093+
</Consumer>
1094+
</Provider>
1095+
)
1096+
}
1097+
}
1098+
1099+
RHL.register(App, 'App', 'test.js')
1100+
1101+
const wrapper = mount(
1102+
<AppContainer>
1103+
<App />
1104+
</AppContainer>,
1105+
)
1106+
1107+
expect(wrapper.contains(<div>{contextValue}</div>)).toBe(true)
1108+
expect(spy).toHaveBeenCalledTimes(1)
1109+
} else {
1110+
expect(true).toBe(true)
1111+
}
1112+
})
1113+
1114+
it('passes provider defined falsy context value', () => {
1115+
if (React.version.startsWith('16')) {
1116+
const spy = jest.fn()
1117+
const contextValue = 0
1118+
const { Provider, Consumer } = React.createContext()
1119+
1120+
class App extends Component {
1121+
render() {
1122+
return (
1123+
<Provider value={contextValue}>
1124+
<Consumer>
1125+
{value => {
1126+
spy(value)
1127+
return <div>{value}</div>
1128+
}}
1129+
</Consumer>
1130+
</Provider>
1131+
)
1132+
}
1133+
}
1134+
1135+
RHL.register(App, 'App', 'test.js')
1136+
1137+
const wrapper = mount(
1138+
<AppContainer>
1139+
<App />
1140+
</AppContainer>,
1141+
)
1142+
1143+
expect(wrapper.contains(<div>{contextValue}</div>)).toBe(true)
1144+
expect(spy).toHaveBeenCalledTimes(1)
1145+
expect(spy).toHaveBeenCalledWith(contextValue)
1146+
} else {
1147+
expect(true).toBe(true)
1148+
}
1149+
})
1150+
1151+
it('passes provider defined falsy context value on receiving new children', () => {
1152+
if (React.version.startsWith('16')) {
1153+
const spy = jest.fn()
1154+
const spy2 = jest.fn()
1155+
const contextValue = false
1156+
const { Provider, Consumer } = React.createContext()
1157+
1158+
class App extends Component {
1159+
render() {
1160+
return (
1161+
<Provider value={contextValue}>
1162+
<Consumer>
1163+
{value => {
1164+
spy(value)
1165+
return <div>{value}</div>
1166+
}}
1167+
</Consumer>
1168+
</Provider>
1169+
)
1170+
}
1171+
}
1172+
1173+
RHL.register(App, 'App', 'test.js')
1174+
1175+
const wrapper = mount(
1176+
<AppContainer>
1177+
<App />
1178+
</AppContainer>,
1179+
)
1180+
1181+
expect(wrapper.contains(<div>{contextValue}</div>)).toBe(true)
1182+
expect(spy).toHaveBeenCalledTimes(1)
1183+
expect(spy).toHaveBeenCalledWith(contextValue)
1184+
1185+
{
1186+
class App extends Component {
1187+
shouldComponentUpdate() {
1188+
return false
1189+
}
1190+
1191+
render() {
1192+
return (
1193+
<Provider value={contextValue}>
1194+
<Consumer>
1195+
{value => {
1196+
spy2(value)
1197+
return <div>{value}</div>
1198+
}}
1199+
</Consumer>
1200+
</Provider>
1201+
)
1202+
}
1203+
}
1204+
1205+
RHL.register(App, 'App', 'test.js')
1206+
wrapper.setProps({ children: <App /> })
1207+
}
1208+
1209+
const firstCallArg = spy2.mock.calls[0][0]
1210+
1211+
expect(spy2).toHaveBeenCalledTimes(2)
1212+
expect(firstCallArg).toBeDefined()
1213+
expect(firstCallArg).toBe(contextValue)
1214+
} else {
1215+
expect(true).toBe(true)
1216+
}
1217+
})
10431218
})
10441219

10451220
describe('with createClass root', () => {

0 commit comments

Comments
 (0)