-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
setState doesn't trigger rerender #134
Changes from 6 commits
6a4a20d
9152440
e314072
3740832
24bb43e
c403880
2af1677
dbeda28
67c442d
4860e51
bb62976
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -31,11 +31,6 @@ export default class Preview extends Component { | |
} | ||
} | ||
|
||
setComponentState(newState) { | ||
this.componentState = {...this.componentState, ...newState}; | ||
setTimeout(this.executeCode.bind(this), 0); | ||
} | ||
|
||
compileCode(code) { | ||
return transform(code, { | ||
presets: ['es2015', 'react', 'stage-0'] | ||
|
@@ -57,15 +52,65 @@ export default class Preview extends Component { | |
} | ||
|
||
try { | ||
code = ` | ||
const state = Object.freeze(${JSON.stringify(this.componentState)}); | ||
${code} | ||
let compiledCode = this.compileCode(this.props.code); | ||
|
||
// the code contains the setup of the state and the react component to render. | ||
// we split the setup of the state and the react component; | ||
|
||
const splitIndex = compiledCode.indexOf('React.createElement'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will it work with ES6 classes and functional components? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In my examples does it work. The React.createElement () is just the result after the JSX transformation. So There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a bad idea. And after the discussion in the PR, I thought we don't need any splitting anymore. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, I also thought that we’ve found a better solution. |
||
|
||
// initiate state and set with the callback in the bottom component; | ||
const initCode = ` | ||
var initialState = {}; | ||
${compiledCode.substring(0, splitIndex)} | ||
__initialStateCB(initialState); | ||
`; | ||
// evalInContext returns a function which takes state, setState and a callback to handle the | ||
// initial state and returns the evaluated code | ||
const initial = this.props.evalInContext(initCode); | ||
|
||
// 1) setup initialState so that we don't get an error; | ||
// 2) use require data or make other setup for the example component; | ||
// 3) return the example component | ||
const renderCode = ` | ||
var initialState = {}; | ||
${compiledCode.substring(0, splitIndex)} | ||
return ${compiledCode.substring(splitIndex)}; | ||
`; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In order to pass the setState Function and the state into our component, we have to use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why not just add more arguments to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what do you mean? I don't see what extra argument could solve the problem. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In
The |
||
let compiledCode = this.compileCode(code); | ||
let component = this.props.evalInContext(compiledCode, this.setComponentState.bind(this)); | ||
const render = this.props.evalInContext(renderCode); | ||
|
||
// wrap everything in a react component, such that we can leverage the state management of this component | ||
class PreviewComponent extends React.Component { | ||
|
||
constructor(props) { | ||
super(props); | ||
|
||
const state = {}; | ||
const initialStateCB = (initialState) => { | ||
Object.assign(state, initialState); | ||
}; | ||
const setStateError = (partialState) => { | ||
const err = 'Calling setState to setup the initial state is deprecated. Use\ninitialState = '; | ||
Object.assign(state, {error: err + JSON.stringify(partialState) + ';'}); | ||
}; | ||
initial({}, setStateError, initialStateCB); | ||
this.state = state; | ||
} | ||
|
||
render() { | ||
if (this.state.error) { | ||
return <pre className={s.playgroundError}>{this.state.error}</pre>; | ||
} | ||
const setState = partialState => this.setState(partialState); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
const state = this.state; | ||
// pass through props from the wrapper component | ||
return React.cloneElement(render(state, setState, null), this.props); | ||
} | ||
} | ||
|
||
let wrappedComponent = ( | ||
<Wrapper> | ||
{component} | ||
<PreviewComponent /> | ||
</Wrapper> | ||
); | ||
ReactDOM.render(wrappedComponent, mountNode); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const
?