A component has props
and can have a state
var MyOldWayComponent = React.createClass({
displayName: 'MyOldWayComponent',
render: function renderOldWayComponent(){
return MyOldWayComponent;
}
});
class MyClassComponent extends React.Component {
render(){
const {state, props} = this;
return (
- Props :{JSON.stringify(props)}
- State: {JSON.stringify(state)}
);
}
}
function MyFunctionComponent(props) {
return Props: {JSON.stringify(props)}
}
props
,state
and also context
Dependency Injection
getChildContext
method must be implementedchildContextTypes
object must be setclass MyAwesomeRootComponent extends React.Component { render(){ return (
Component Awesome <Child1/> {this.props.children}); } getChildContext(){ return {color: "purple"}; } }MyAwesomeRootComponent.childContextTypes = { color: React.PropTypes.string }
context
object is in the component's this
childContextTypes
object must be setclass ComponentUsingContext extends React.Component { render(){ const {color} = this.context; return
{color}; } }ComponentUsingContext.contextTypes = { color: React.PropTypes.string }
function MyFuncComponent(props, context){ const {color} = this.context; return
{color}; } }MyFuncComponent.contextTypes = { color: React.PropTypes.string }
function App(props){
return (
<MyAwesomeRootComponent>
App
<Child1 />
<Child2 />
<Child3 />
</MyAwesomeRootComponent>
);
}
render(<App/>, document.querySelector("div#root"));
class Parent extends React.Component { render(){ const {lang} = this.props; return (
<Child lang={lang}>); } }function Child({lang}){ return (
<GrandChild lang={lang}>); }function GrandChild({lang}){ return (
{lang}); }
ReactDOM.render(<Parent lang='fr'/>, document.querySelector('div#app'));
JSBIN
Child
only transfers the lang
to the GrandChild
without needing itprops
transfer is hard to maintain due to couplingThis problem is even more a pain when you need to abstract things in your components.
Context
?
class Parent extends React.Component {
getChildContext(){
return {this.props.lang};
}
render(){
return (
Parent
<Child>
);
}
}
Parent.childContextTypes = {
lang: React.PropTypes.string
};
function Child(props){ return (
); }Child
<GrandChild>function GrandChild(props, {lang}){ return (
); }Child
{lang}GrandChild.contextTypes = { lang: PropTypes.string }
ReactDOM.render(<Parent lang='fr'/>, document.querySelector('div#app'))
childContextTypes
and contextType
childContextTypes
is a pain to write on each timeCan we be inspired by something great?
reducer
react-redux
there is a simple pattern which is Connect
and Provider
object
import { createStore } from 'redux'
import { Provider } from 'react-redux'
import App from './containers/App'
import todoApp from './reducers'
let store = createStore(todoApp);
let rootElement = document.getElementById('root')
const ConnectedApp = connect(getState)(App)
render(
<Provider store={store}>
<ConnectedApp />
</Provider>,
rootElement
)
a LangProvider
and LangConnector
class Parent extends React.Component {
render(){
return (
Parent
<Child/>
);
}
}
function Child({lang}){ return (
); }Child
<GrandChild />function GrandChild({lang}){ return (
); }GrandChild
{lang}connectLang(GrandChild); ReactDOM.render(<LangProvider lang='fr'><Parent/></LangProvider>, document.querySelector('div#app'))
pure
LangProvider
?class LangProvider extends React.Component { getChildContext(){ return {lang: this.props.lang}; } render() { return this.props.children; } }
Provider.childContextTypes = { lang: React.PropTypes.string };
LangConnector
?
function connectLang(ComponentToConnect){
class ConnectedOnLang extends React.Component {
render() {
const {lang} = this.context;
return <ComponentToConnect lang={lang} {...this.props} /> ;
}
}
ConnectedOnLang.displayName = `${ComponentToConnect.displayName}ConnectedOnLang`;
ConnectedOnLang.contextTypes = {
lang: React.PropTypes.string.isRequired
};
return ConnectedOnLang;
}
void componentWillReceiveProps(object nextProps, object nextContext)
boolean shouldComponentUpdate(object nextProps, object nextState, object nextContext)
void componentWillUpdate(object nextProps, object nextState, object nextContext)
void componentDidUpdate(object prevProps, object prevState, object prevContext)
RouteComponent
, RouteComponent
React utility belt for function components and higher-order components
{
movie: {
code: {
domain: 'DO_ID',
required: true
},
title: {
domain: 'DO_LABEL_LONG',
required: true
},
originalTitle: {
domain: 'DO_LABEL_LONG',
required: false
}
}
}
When you cannot convert your mixin in an Higher Order Component
props
when you can
When you want to abstract something
For things such as current user, language, theme, metadata.
Every where you would have use a global variable or a separate module.
When you wan to abstract a behaviour (often use to be complex mixins).