-
Notifications
You must be signed in to change notification settings - Fork 1
Basic Example
The following is a simple color-picker, where we display a list of colors, and allow a single color to be selected.
In this example, we must pass down both an application-level state property (selectedColor
),
as well as an action function (changeColor
), all the way from the ColorList
top-level component to the ColorOptions
grand-child components:
// app.js, the "entrypoint" of the app.
import ColorList from './components/ColorList';
ReactDOM.render(
React.createElement(ColorList),
document.getElementById('root')
);
// ColorList.jsx, displays the list of colors
import Color from './Color';
class ColorList extends React.Component {
constructor(props) {
super(props);
this.state = { selectedColor: props.colors[0] };
this.changeColor = this.changeColor.bind(this);
}
changeColor(color) {
this.setState({selectedColor: color});
}
render() {
return (
<div>
<p>
The selected color is {this.state.selectedColor}
</p>
<div>
{this.props.colors.map(color =>
<Color
key={color}
color={color}
changeColor={this.changeColor}
selectedColor={this.state.selectedColor}
/>
)}
</div>
</div>
);
}
static get defaultProps() {
return {
colors: ['red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet']
};
}
}
export default ColorList;
// Color.jsx, each list item
import ColorOptions from './ColorOptions';
function Color(props) {
return (
<div>
<span>This color is {props.color}</span>
<ColorOptions
color={props.color}
changeColor={props.changeColor}
selectedColor={props.selectedColor}
/>
</div>
);
}
export default Color;
// ColorOptions.jsx, displays the relevant options for a particular color.
function ColorOptions(props) {
return (
<div>
<span>Replace {props.selectedColor} with {props.color}?</span>
<button onClick={e => props.changeColor(props.color)}>yes</button>
</div>
);
}
export default ColorOptions;
Let's "redu" it. Our goal will be to eliminate the number of props that we need to pass down from the ColorList
to the ColorOptions
components.
To accomplish this, we will move all of the shared application-level state and action functions out of the ColorList
component and into the ColorListStore
. We will then subscribe the ColorList
and the ColorOptions
to the ColorListStore
in order to derive what we need from it.
// app.js, the "entrypoint" of the app.
import ColorListStore from './stores/ColorListStore';
ReactDOM.render(
React.createElement(ColorListStore),
document.getElementById('root')
);
// ColorListStore.js, creates the application-level store.
import { createStore } from 'redu';
import ColorList from '../components/ColorList';
const ColorListStore = createStore(ColorList);
ColorListStore.defaultProps = {
colors: ['red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet']
};
ColorListStore.initialState = {
selectedColor: ColorListStore.defaultProps.colors[0]
};
ColorListStore.actions = {
changeColor(color) {
this.setState({
selectedColor: color
});
}
};
export default ColorListStore;
// ColorList.jsx, displays the list of colors
import { createSubscriber } from 'redu';
import Color from './Color';
function ColorList(props) {
return (
<div>
<p>
The selected color is {props.selectedColor}
</p>
<div>
{props.colors.map(color =>
<Color key={color} color={color} />
)}
</div>
</div>
);
}
export default createSubscriber(ColorList, (colorListStoreState, colorListStoreProps) => {
return {
selectedColor: colorListStoreState.selectedColor,
colors: colorListStoreProps.colors
};
});
// Color.jsx, each list item
import ColorOptions from './ColorOptions';
function Color(props) {
return (
<div>
<span>This color is {props.color}</span>
<ColorOptions color={props.color} />
</div>
);
}
export default Color;
// ColorOptions.jsx, displays the relevant options for a particular color.
import { createSubscriber } from 'redu';
function ColorOptions(props) {
return (
<div>
<span>Replace {props.selectedColor} with {props.color}?</span>
<button onClick={e => props.changeColor(props.color)}>yes</button>
</div>
);
}
export default createSubscriber(ColorOptions, (colorListStoreState, colorListStoreProps, colorListStoreActions) => {
return {
selectedColor: colorListStoreState.selectedColor,
changeColor: colorListStoreActions.changeColor
};
});
Notice that we've solved problem #1 by eliminating threading props down multiple levels,
and solved problem #2 via the ColorListStore.js
, which, when viewed, gives a very good sense of what this app does.
And of course, problem #3 is solved as well, since we had no need to create action creators or reducers.