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

[v7-beta] Update outdated SSR-test - dispatch in ancestors #1213

Merged
merged 1 commit into from
Mar 22, 2019
Merged
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
92 changes: 43 additions & 49 deletions test/integration/server-rendering.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,28 @@ describe('React', () => {
</div>
)

class Dispatcher extends React.Component {
constructor(props) {
super(props)
if (props.constructAction) {
props.dispatch(props.constructAction)
}
}
UNSAFE_componentWillMount() {
if (this.props.willMountAction) {
this.props.dispatch(this.props.willMountAction)
}
}
render() {
if (this.props.renderAction) {
this.props.dispatch(this.props.renderAction)
}

return <Greeter greeted={this.props.greeted} />
}
}
const ConnectedDispatcher = connect()(Dispatcher)

it('should be able to render connected component with props and state from store', () => {
const store = createStore(greetingReducer)

Expand Down Expand Up @@ -71,48 +93,43 @@ describe('React', () => {
expect(store.getState().greeting).toContain('Hi')
})

it.skip('should render children with original state even if actions are dispatched in ancestor', () => {
it('should render children with updated state if actions are dispatched in ancestor', () => {
/*
Dispatching during construct, render or willMount is
almost always a bug with SSR (or otherwise)

This behaviour is undocumented and is likely to change between
implementations, this test only verifies current behaviour

Note: this test passes in v6, because we use context to propagate the store state, and the entire
Note: this test fails in v6, because we use context to propagate the store state, and the entire
tree will see the same state during the render pass.

In all other versions, including v7, the store state may change as actions are dispatched
during lifecycle methods, and components will see that new state immediately as they read it.
*/
const store = createStore(greetingReducer)

class Dispatcher extends React.Component {
constructor(props) {
super(props)
props.dispatch(props.action)
}
UNSAFE_componentWillMount() {
this.props.dispatch(this.props.action)
}
render() {
this.props.dispatch(this.props.action)

return <Greeter greeted={this.props.greeted} />
}
}
const ConnectedDispatcher = connect()(Dispatcher)

const action = { type: 'Update', payload: { greeting: 'Hi' } }
const constructAction = { type: 'Update', payload: { greeting: 'Hi' } }
const willMountAction = { type: 'Update', payload: { greeting: 'Hiya' } }
const renderAction = { type: 'Update', payload: { greeting: 'Hey' } }

const markup = renderToString(
<Provider store={store}>
<ConnectedDispatcher action={action} greeted="world" />
<ConnectedDispatcher
constructAction={constructAction}
greeted="world"
/>
<ConnectedDispatcher
willMountAction={willMountAction}
greeted="world"
/>
<ConnectedDispatcher renderAction={renderAction} greeted="world" />
</Provider>
)

expect(markup).toContain('Hello world')
expect(store.getState().greeting).toContain('Hi')
expect(markup).toContain('Hi world')
expect(markup).toContain('Hiya world')
expect(markup).toContain('Hey world')
expect(store.getState().greeting).toContain('Hey')
})

it('should render children with changed state if actions are dispatched in ancestor and new Provider wraps children', () => {
Expand All @@ -122,35 +139,12 @@ describe('React', () => {

This behaviour is undocumented and is likely to change between
implementations, this test only verifies current behaviour

This test works both when state is fetched directly in connected
components and when it is fetched in a Provider and placed on context
*/
const store = createStore(greetingReducer)

class Dispatcher extends React.Component {
constructor(props) {
super(props)
if (props.constructAction) {
props.dispatch(props.constructAction)
}
}
UNSAFE_componentWillMount() {
if (this.props.willMountAction) {
this.props.dispatch(this.props.willMountAction)
}
}
render() {
if (this.props.renderAction) {
this.props.dispatch(this.props.renderAction)
}

return (
<Provider store={store}>
<Greeter greeted={this.props.greeted} />
</Provider>
)
}
}
const ConnectedDispatcher = connect()(Dispatcher)

const constructAction = { type: 'Update', payload: { greeting: 'Hi' } }
const willMountAction = { type: 'Update', payload: { greeting: 'Hiya' } }
const renderAction = { type: 'Update', payload: { greeting: 'Hey' } }
Expand Down