【React-Redux】Redux-Saga と `select` effect を使って State/Store から値を取得する方法
JavaScript、ReactJS、Redux における Redux-Saga 関数内で State/Store から値を取得する方法
Redux-Saga は、非同期処理を管理するための Redux ミドルウェアです。Redux-Saga 関数内で State/Store から値を取得するには、select
effect を使用します。
手順
redux-saga/effects
からselect
をインポートします。select
effect を使用して、State/Store から取得したい値を指定するセレクター関数を渡します。yield
を使用して、select
effect の結果を待機します。
例
import { select } from 'redux-saga/effects';
function* mySaga() {
const userId = yield select(state => state.user.id);
console.log(`User ID: ${userId}`);
}
この例では、mySaga
関数は select
effect を使用して state.user.id
を取得し、コンソールにログ出力します。
yield
を使用して、非同期処理の結果を待機する必要があります。- セレクター関数は、State/Store から必要な値を抽出するために使用されます。
- ReactJS で Redux を使用するには、
react-redux
パッケージを使用する必要があります。 - Redux-Saga以外にも、State/Store から値を取得するための方法はいくつかあります。詳細は、Redux のドキュメントを参照してください。
├── actions
│ └── userActions.js
├── sagas
│ └── userSaga.js
├── store
│ ├── index.js
│ └── reducers
│ └── userReducer.js
└── App.js
コード
actions/userActions.js
export const FETCH_USER_REQUEST = 'FETCH_USER_REQUEST';
export const FETCH_USER_SUCCESS = 'FETCH_USER_SUCCESS';
export const FETCH_USER_FAILURE = 'FETCH_USER_FAILURE';
export const fetchUserRequest = () => ({
type: FETCH_USER_REQUEST,
});
export const fetchUserSuccess = (user) => ({
type: FETCH_USER_SUCCESS,
payload: user,
});
export const fetchUserFailure = (error) => ({
type: FETCH_USER_FAILURE,
payload: error,
});
sagas/userSaga.js
import { takeEvery, put, call } from 'redux-saga/effects';
import { FETCH_USER_REQUEST, fetchUserSuccess, fetchUserFailure } from '../actions/userActions';
import userService from '../services/userService';
function* fetchUser() {
try {
const user = yield call(userService.fetchUser);
yield put(fetchUserSuccess(user));
} catch (error) {
yield put(fetchUserFailure(error));
}
}
export default function* userSaga() {
yield takeEvery(FETCH_USER_REQUEST, fetchUser);
}
store/index.js
import { createStore, applyMiddleware } from 'redux';
import rootReducer from './reducers';
import rootSaga from '../sagas';
import logger from 'redux-logger';
const store = createStore(rootReducer, applyMiddleware(rootSaga, logger));
export default store;
store/reducers/userReducer.js
const initialState = {
user: null,
loading: false,
error: null,
};
export default function userReducer(state = initialState, action) {
switch (action.type) {
case FETCH_USER_REQUEST:
return {
...state,
loading: true,
error: null,
};
case FETCH_USER_SUCCESS:
return {
...state,
loading: false,
user: action.payload,
};
case FETCH_USER_FAILURE:
return {
...state,
loading: false,
error: action.payload,
};
default:
return state;
}
}
App.js
import React from 'react';
import { connect } from 'react-redux';
import { fetchUser } from './actions/userActions';
class App extends React.Component {
componentDidMount() {
this.props.dispatch(fetchUser());
}
render() {
const { user, loading, error } = this.props;
if (loading) {
return <div>Loading...</div>;
}
if (error) {
return <div>Error: {error.message}</div>;
}
if (!user) {
return <div>No user found</div>;
}
return (
<div>
<h1>{user.name}</h1>
<p>{user.email}</p>
</div>
);
}
}
const mapStateToProps = (state) => ({
user: state.user.user,
loading: state.user.loading,
error: state.user.error,
});
export default connect(mapStateToProps)(App);
説明
userSaga.js
にあるfetchUser
関数は、非同期的に API を呼び出し、ユーザーデータをフェッチします。select
effect を使用して、userSaga.js
関数内で State/Store から値を取得しています。App.js
コンポーネントは、mapStateToProps
関数を使用して State/Store から値を取得し、UI にレンダリングします。
getState 関数を使用する
import { getState } from 'redux';
function* mySaga() {
const userId = getState().user.id;
console.log(`User ID: ${userId}`);
}
この例では、getState
関数を使用して State/Store 全体を取得し、user.id
プロパティに直接アクセスしています。
connect 関数を使用する
import React from 'react';
import { connect } from 'react-redux';
const MyComponent = ({ userId }) => (
<div>
<h1>User ID: {userId}</h1>
</div>
);
const mapStateToProps = (state) => ({
userId: state.user.id,
});
export default connect(mapStateToProps)(MyComponent);
この例では、connect
関数を使用して、MyComponent
コンポーネントに userId
プロパティを直接渡しています。
withRedux HOC を使用する
import React from 'react';
import { withRedux } from 'react-redux';
const MyComponent = ({ userId }) => (
<div>
<h1>User ID: {userId}</h1>
</div>
);
export default withRedux(mapStateToProps)(MyComponent);
useSelector フックを使用する (React >= 17)
import React from 'react';
import { useSelector } from 'react-redux';
const MyComponent = () => {
const userId = useSelector(state => state.user.id);
return (
<div>
<h1>User ID: {userId}</h1>
</div>
);
};
export default MyComponent;
この例では、useSelector
フックを使用して、state.user.id
セレクター関数を直接使用しています。
どの方法を選択するかは、状況によって異なります。
connect
関数、withRedux
HOC、またはuseSelector
フックは、React コンポーネントで State/Store から値を取得する場合に適しています。getState
関数は、単純な値を取得する場合に適しています。select
effect は、非同期処理や複雑なセレクター関数を扱う場合に適しています。
javascript reactjs redux