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

WRO-9096: Update react-redux related documentation #3081

Merged
merged 26 commits into from
Aug 23, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
58 changes: 31 additions & 27 deletions docs/redux/redux-async.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,30 +55,25 @@ render(
Store is configured to accept thunk middleware

```js
import {createStore, applyMiddleware} from 'redux';
import {configureStore, createSlice} from '@reduxjs/toolkit';
import thunkMiddleware from 'redux-thunk';
import systemSettingsReducer from '../reducers';
import rootSlice from '../reducers';

export default function configureStore (initialState) {
const store = createStore(
systemSettingsReducer,


export default function configureAppStore (initialState) {
return configureStore({
reducer: rootSlice.reducer,
initialState,
applyMiddleware(thunkMiddleware) // lets us dispatch functions
);
return store;
middleware: [thunkMiddleware]
vladut-clapou-lgp marked this conversation as resolved.
Show resolved Hide resolved
});
}
```

Here we create a thunk action creator which returns a function instead of a plain object. It is also possible to dispatch an action or request at the beginning.

```js
import LS2Request from '@enact/webos/LS2Request';
function receiveSystemSettings (res) {
return {
type: 'RECEIVE_SYSTEM_SETTINGS',
payload: res
};
}
// function returning function!
export const getSystemSettings = params => dispatch => {
// possible to dispatch an action at the start of fetching
Expand All @@ -98,24 +93,33 @@ export const getSystemSettings = params => dispatch => {
Reducer receives a payload and creates a new state.

```js
export default function systemSettingsReducer (state = {}, action) {
switch (action.type) {
case 'RECEIVE_SYSTEM_SETTINGS':
const rootSlice = createSlice({
name: 'systemReducer',
initialState: {},
reducers: {
receiveSystemSettings: (state, action) => {
return Object.assign({}, state, action.payload.settings);
},
updateSystemSettings: (state, action) => {
return Object.assign({}, state, action.payload.settings);
default:
return state;
}
}
}
});

export const {receiveSystemSettings, updateSystemSettings} = rootSlice.actions;
export default rootSlice;
```

Connected container dispatches ``getSystemSettings`` on componentDidMount and renders a ``pictureMode`` prop that's been hooked up with a redux store.
Connected container dispatches ``getSystemSettings`` on component mout and renders a ``pictureMode`` prop that's been hooked up with a redux store.
vladut-clapou-lgp marked this conversation as resolved.
Show resolved Hide resolved

```js
import {Component} from 'react';
import {connect} from 'react-redux';
import {getSystemSettings} from '../actions';
import {useDispatch, useSelector} from 'react-redux';
import {getSystemSettings} from '../reducers';

const App = () => {
const pictureMode = useSelector(store => store.pictureMode);
const dispatch = useDispatch();

const App = ({dispatch}) => {
useEffect(() => {
dispatch(getSystemSettings({
category: 'picture',
Expand All @@ -124,8 +128,8 @@ const App = ({dispatch}) => {
}));
}, []);

return <p>{this.props.pictureMode}</p>;
return <p>{pictureMode}</p>;
}

export default connect()(App);
export default App;
```
127 changes: 59 additions & 68 deletions docs/redux/redux-intro.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ This document provides a high-level overview of Redux and how it is used.
### What is Redux?

Redux is a library that allows you to manage application state. It closely follows React's Flux data flow model and works well with React, though it does not require it. State management has become more complicated due to a mixing of mutability and asynchronicity, and redux tries to resolve this issue by make state mutation **predictable**.
State management has become more complicated due to a mixing of mutability and asynchronicity, and redux tries to resolve this issue by make state mutation **predictable**.

We recommend using the most recent version of Redux. To see which version of Redux is appropriate, refer to the [Redux Installation Instructions](https://react-redux.js.org/introduction/quick-start#installation).

Expand Down Expand Up @@ -155,9 +154,10 @@ Live demo: [http://jsbin.com/keyahus/edit?html,js,output](http://jsbin.com/keyah
#### React

```js
import {createRoot} from 'react-dom/client';
import {createStore} from 'redux';
import PropTypes from 'prop-types';
import { createRoot } from 'react-dom/client';
import { useDispatch, useSelector } from 'react-redux';

// reducer
function counter (state = 0, action) {
switch (action.type) {
Expand All @@ -167,36 +167,32 @@ function counter (state = 0, action) {
return state;
}
}
vladut-clapou-lgp marked this conversation as resolved.
Show resolved Hide resolved
const Counter = ({value, onIncrement}) => {
return (
<p>
Clicked: {value} times
{' '}
<button onClick={onIncrement}>
+
</button>
</p>
);
}
Counter.propTypes = {
onIncrement: PropTypes.func.isRequired,
value: PropTypes.number.isRequired
const Counter = () => {
const value = useSelector((state) => state.counter);
const dispatch = useDispatch();

const incrementHandler = () => {
dispatch({ type: 'INCREMENT' });
};

return (
<p>
Clicked: {value} times <button onClick={incrementHandler}>+</button>
</p>
);
};

const store = createStore(counter);
const render = () => {
const appElement = (
<Counter
value={store.getState()}
onIncrement={() => store.dispatch({type: 'INCREMENT'})}
/>
<Counter/>
);
createRoot(document.getElementById('root')).render(appElement);
}
render();
store.subscribe(render);
```

Live Demo: [https://jsbin.com/pudurig/edit?html,js,output](https://jsbin.com/pudurig/edit?html,js,output)
Live Demo: [https://stackblitz.com/edit/react-u1qccn?file=src%2Fstore%2Findex.js,src%2Findex.js,src%2FApp.js](https://stackblitz.com/edit/react-u1qccn?file=src%2Fstore%2Findex.js,src%2Findex.js,src%2FApp.js)

### Redux Toolkit

Expand Down Expand Up @@ -233,56 +229,51 @@ Our components need access to the Redux store so they can subscribe to it. This
#### example
vladut-clapou-lgp marked this conversation as resolved.
Show resolved Hide resolved

```js
import {createRoot} from 'react-dom/client';
vladut-clapou-lgp marked this conversation as resolved.
Show resolved Hide resolved
import {createStore} from 'redux';
vladut-clapou-lgp marked this conversation as resolved.
Show resolved Hide resolved
import {connect, Provider} from 'react-redux';
import PropTypes from 'prop-types';
import {Component} from 'react';
import {render} from 'react-dom';
import {Provider, useDispatch, useSelector} from 'react-redux';

// reducer
function counter (state = 0, action) {
switch (action.type) {
case 'INCREMENT':
return state + 1;
default:
return state;
}
}
// presentational counter component
class Counter extends Component {
render () {
const {value, onIncrement} = this.props;
return (
<p>
Clicked: {value} times
{' '}
<button onClick={onIncrement}>
+
</button>
</p>
);
}
}
const mapStateToProps = (state) => {
return {value: state};
const counterReducer = (state = { counter: 0 }, action) => {
switch (action.type) {
case 'INCREMENT':
return { counter: state.counter + 1 };
default:
return state;
}
};
const mapDispatchToProps = (dispatch) => {
return {
onIncrement: () => dispatch({type: 'INCREMENT'})
};

//store
const store = createStore(counterReducer);
vladut-clapou-lgp marked this conversation as resolved.
Show resolved Hide resolved

// presentational counter component
const Counter = () => {
const value = useSelector((state) => state.counter);
const dispatch = useDispatch();

const incrementHandler = () => {
dispatch({ type: 'INCREMENT' });
};

return (
<p>
Clicked: {value} times <button onClick={incrementHandler}>+</button>
</p>
);
};
// creates a connected container component with `connect`
const EnhancedCounter = connect(mapStateToProps, mapDispatchToProps)(Counter);
const store = createStore(counter);
class App extends Component {
render () {
return (
<Provider store={store}>
<EnhancedCounter />
</Provider>
);
}

const App = () => {
return <Counter />;
}
render(<App />, document.getElementById('root'));

const rootElement = document.getElementById('root');
const root = createRoot(rootElement);

root.render(
<Provider store={store}>
<App />
</Provider>
);
```

Live Demo: [http://jsbin.com/zukojok/1/edit?html,js,output](http://jsbin.com/zukojok/1/edit?html,js,output)
vladut-clapou-lgp marked this conversation as resolved.
Show resolved Hide resolved
Expand Down