Taleymirza | TaleyaMirza | TaleyaMirza | ||||
---|---|---|---|---|---|---|
const UserAvatar = ({ user, size }) => (
<img
className={`user-avatar ${size || ""}`}
alt="user avatar"
src={user.avatar}
/>
);
const UserStats = ({ user }) => (
<div className="user-stats">
<div>
<UserAvatar user={user} />
{user.name}
</div>
<div className="stats">
<div>{user.followers} Followers</div>
<div>Following {user.following}</div>
</div>
</div>
);
const Nav = ({ user }) => (
<div className="nav">
<UserAvatar user={user} size="small" />
</div>
);
const Content = () =>
<div className="content">main content here</div>;
const Sidebar = ({ user }) => (
<div className="sidebar">
<UserStats user={user} />
</div>
);
const Body = ({ user }) => (
<div className="body">
<Sidebar user={user} />
<Content />
</div>
);
class App extends React.Component {
state = {
user: {
avatar:
"https://www.gravatar.com/avatar/5c3dd2d257ff0e14dbd2583485dbd44b",
name: "Dave",
followers: 1234,
following: 123
}
};
render() {
const { user } = this.state;
return (
<div className="app">
<Nav user={user} />
<Body user={user} />
</div>
);
}
}
As Pete Hunt, one of the early contributors to React, says:
You'll know when you need Flux. If you aren't sure if you need it, you don't need it.
Similarly, Dan Abramov, one of the creators of Redux, says:
I would like to amend this: don't use Redux until you have problems with vanilla React.
(with predictable behavior)
const initialState = {};
function reducer(state = initialState, action) {
switch (action.type) {
// Respond to the SET_USER action and update
// the state accordingly
case "SET_USER":
return {
...state,
user: action.user
};
default:
return state;
}
}
Create a reducer with an empty initial state
const store = createStore(reducer);
Create the store with the reducer
// (since initial state is empty)
store.dispatch({
type: "SET_USER",
user: {
avatar: "https://www.gravatar.com/avatar/5c3dd2d257ff0e14dbd2583485dbd44b",
name: "Dave",
followers: 1234,
following: 123
}
});
Dispatch an action to set the user
const mapStateToProps = state => ({
user: state.user
});
This mapStateToProps function extracts a single key from state (user) and passes it as the `user` prop
const UserAvatar = connect(mapStateToProps)(({ user, size }) => (
<img
className={`user-avatar ${size || ""}`}
alt="user avatar"
src={user.avatar}
/>
));
Connect() UserAvatar & UserStats
so it receives the `user` directly, without having to receive it from a component above
const UserStats = connect(mapStateToProps)(({ user }) => (
<div className="user-stats">
<div>
<UserAvatar user={user} />
{user.name}
</div>
<div className="stats">
<div>{user.followers} Followers</div>
<div>Following {user.following}</div>
</div>
</div>
));
both use the same mapStateToProps function
const Nav = () => (
<div className="nav">
<UserAvatar size="small" />
</div>
);
const Body = () => (
<div className="body">
<Sidebar />
<Content />
</div>
);
const Sidebar = () => (
<div className="sidebar">
<UserStats />
</div>
);
const Content = () => <div className="content">main content here</div>;
Nav, Sidebar and Body doesn't need to know about `user` anymore
const App = () => (
<div className="app">
<Nav />
<Body />
</div>
);
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.querySelector("#root")
);
Wrap the whole app in Provider so that connect() has access to the store
const UserContext = React.createContext();
Create a Context
class App extends React.Component {
state = {
user: {
avatar:
"https://www.gravatar.com/avatar/5c3dd2d257ff0e14dbd2583485dbd44b",
name: "Dave",
followers: 1234,
following: 123
}
};
render() {
return (
<div className="app">
<UserContext.Provider value={this.state.user}>
<Nav />
<Body />
</UserContext.Provider>
</div>
);
}
}
we pass the context down through the tree using the Provider
Components that need the data tap into the context by using its Consumer property
const UserAvatar = ({ size }) => (
<UserContext.Consumer>
{user => (
<img
className={`user-avatar ${size || ""}`}
alt="user avatar"
src={user.avatar}
/>
)}
</UserContext.Consumer>
);
const UserStats = () => (
<UserContext.Consumer>
{user => (
<div className="user-stats">
<div>
<UserAvatar user={user} />
{user.name}
</div>
<div className="stats">
<div>{user.followers} Followers</div>
<div>Following {user.following}</div>
</div>
</div>
)}
</UserContext.Consumer>
);
Screw driver vs. Impact Driver
The reports of my death are greatly exaggerated
- Mark Twain
No.
Taleymirza | TaleyaMirza | TaleyaMirza | ||||
---|---|---|---|---|---|---|