درباره نویسنده
Fortune Ikechi یک مهندس Frontend است که در Rivers State نیجریه مستقر است. وی دانشجوی دانشگاه پورت-هارکورت است. او عاشق اجتماع و … است
بیشتر در مورد
ثروت
…
state
، قطعاً با کاهنده ها روبرو شده اید. این آموزش مفهوم کاهش دهنده ها و نحوه کار آنها به طور خاص در Redux را توضیح می دهد.
در این آموزش ، ما می خواهیم مفهوم کاهش دهنده ها و نحوه کار آنها ، به ویژه در برنامه های React را بیاموزیم. به منظور درک و استفاده بهتر از Redux ، درک کامل کاهنده ها ضروری است. گیرنده ها روشی را برای به روزرسانی وضعیت برنامه با استفاده از یک عملکرد ارائه می دهند. این یک بخش جدایی ناپذیر از کتابخانه Redux است.
این آموزش برای توسعه دهندگانی است که می خواهند در مورد Redux Reducers بیشتر بدانند. درک React و Redux مفید خواهد بود. در پایان آموزش ، باید درک بهتری از نقشی که Reducers در Redux بازی می کنند داشته باشید. ما برای درک بهتر گیرنده ها و تأثیر آن بر وضعیت در یک برنامه ، دموی کد و برنامه ای را خواهیم نوشت.
کاهش دهنده چیست
Reducer یک تابع خالص است که حالت یک برنامه و عمل را به عنوان آرگومان می گیرد و یک حالت جدید برمی گرداند. به عنوان مثال ، یک احراز هویت می تواند حالت اولیه یک برنامه را به صورت یک شی خالی و عملی را که به او می گوید یک کاربر وارد سیستم شده و یک حالت برنامه جدید را با یک کاربر وارد شده برگرداند ، انجام دهد.
توابع خالص توابعی هستند که هیچگونه عارضه جانبی ندارند و در صورت تصویب همان استدلال ها ، نتایج مشابهی را برمی گردانند.
در زیر مثالی از یک تابع خالص آورده شده است:
const add = (x, y) => x + y;
add(2, 5);
مثال بالا در صورت عبور ، مقداری را بر اساس ورودی ها برمی گرداند 2
و 5
پس همیشه می گرفتی 10
، تا زمانی که همان ورودی باشد هیچ چیز دیگری بر خروجی شما تأثیر نمی گذارد ، این نمونه ای از یک تابع خالص است.
در زیر مثالی از تابع کاهنده آورده شده است که حالت و عملی را انجام می دهد.
const initialState = {};
const cartReducer = (state = initialState, action) => {
// Do something here
}
بیایید دو پارامتر را که یک کاهنده استفاده می کند تعریف کنیم ، state
و action
.
دولت
آ حالت داده ای است که م componentلفه (های) شما با آن کار می کنند – داده های مورد نیاز یک م holdsلفه را در خود نگه می دارد و آنچه را که م componentلفه ارائه می دهد حکم می کند. یک بار در state
شی تغییر می کند ، جز component دوباره ارائه می شود. اگر یک حالت برنامه توسط Redux مدیریت شود ، در آن صورت کاهنده جایی است که تغییرات حالت اتفاق می افتد.
عمل
یک عمل، شی ای است که حاوی محموله اطلاعات است. آنها تنها منبع اطلاعاتی فروشگاه Redux برای به روزرسانی هستند. گیرنده ها فروشگاه را بر اساس مقدار action.type
. در اینجا ما تعریف خواهیم کرد action.type
مانند ADD_TO_CART
.
طبق گفته Redux رسمی مستندات، اقدامات تنها مواردی هستند که باعث تغییر در یک برنامه Redux می شوند ، آنها حاوی محموله برای تغییرات در یک فروشگاه برنامه هستند. عملکردها اشیا Java جاوا اسکریپت هستند که به Redux نوع عملی را که باید انجام شود می گویند ، معمولاً به صورت توابع مانند عملکرد زیر تعریف می شوند:
const action = {
type: 'ADD_TO_CART',
payload: {
product: 'margarine',
quantity: 4
}
}
کد بالا یک نوع معمولی است payload
مقداری که شامل آنچه کاربر برای آن ارسال می کند ، است و از آن برای به روزرسانی وضعیت برنامه استفاده می شود. همانطور که از بالا مشاهده می کنید ، شی action اکشن شامل نوع عمل و یک جسم محموله است که برای انجام این عمل خاص ضروری است.
به روزرسانی حالت با استفاده از گیربکس ها
برای نشان دادن نحوه کارکرد گیرنده ها ، بیایید به شمارنده اعداد زیر نگاه کنیم:
const increaseAction = {
type: 'INCREASE',
};
const decreaseAction = {
type: 'DECREASE'
};
const countReducer = (state = 0, action) => {
switch(action.type){
case INCREASE:
return state + 1;
case DECREASE :
return state -1;
default:
return state;
}
};
در کد بالا ، increaseAction
و decreaseAction
اقداماتی هستند که در کاهنده برای تعیین اینکه چه چیزی استفاده می شود state
به به روز شده است. بعد ، ما یک تابع کاهنده داریم به نام countReducer
، که در می گیرد action
و یک اولیه state
که ارزش آن است 0
. اگر مقدار action.type
است INCREASE
، ما حالت جدیدی را برمی گردانیم که با 1 افزایش می یابد ، اگر اینگونه باشد ، دیگری است DECREASE
حالت جدیدی که با 1 کاهش یابد بازگردانده می شود. در مواردی که منظور هیچ یک از آن شرایط نباشد ، برمی گردیم state
.
به روزرسانی وضعیت با استفاده از گیربکس ها: اپراتور Spread
حالت را نمی توان مستقیم تغییر داد ، برای ایجاد یا به روزرسانی حالت ، می توانیم از JavaScript استفاده کنیم اپراتور گسترش برای اطمینان از اینکه ما مقدار حالت را مستقیماً تغییر نمی دهیم بلکه در عوض یک شی object جدید را که حاوی حالتی است که به آن منتقل شده و بار کاربری کاربر را بازگردانیم.
const contactAction = {
type: 'GET_CONTACT',
payload: ['0801234567', '0901234567']
};
const initialState = {
contacts: [],
contact: {},
};
export default function (state = initialState, action) {
switch (action.type) {
case GET_CONTACTS:
return {
...state,
contacts: action.payload,
};
default:
return state;
}
در کد بالا ، ما از یک اپراتور spread استفاده می کنیم تا مطمئن شویم که مقدار حالت را مستقیماً تغییر نمی دهیم ، به این ترتیب می توانیم یک شی new جدید را پر کنیم با حالتی که به آن منتقل شده و محموله ای که توسط آن ارسال می شود کاربر. با استفاده از یک اپراتور spread ، می توانیم اطمینان حاصل کنیم که حالت همانطور که همه موارد جدید را به آن اضافه می کنیم ثابت بماند و اگر قبلاً موجود بود ، فیلد مخاطبین را نیز جایگزین کنیم.
Redux Reducers in Action – نسخه ی نمایشی
برای درک بهتر Redux Reducers و نحوه کار آنها ، ما یک برنامه ساده جستجوی جزئیات فیلم را اجرا خواهیم کرد ، کد و نسخه کار را می توان در اینجا یافت جعبه کد. برای شروع ، به ترمینال خود بروید و با استفاده از دستور زیر برنامه واکنش را اولیه کنید:
create-react-app movie-detail-finder
پس از آغاز پروژه ، بیایید بسته های مورد نیاز برنامه خود را نصب كنیم.
npm i axios reactstrap react-redux redux redux-thunk
پس از نصب بسته ها ، بیایید با استفاده از دستور سرور توسعه خود را شروع کنیم:
npm start
دستور بالا باید سرور توسعه پروژه ما را در مرورگر ما شروع کند. بعد بیایید پروژه خود را در ویرایشگر متن انتخابی خود ، در داخل پروژه خود باز کنیم src
پوشه ها ، پرونده های زیر را حذف کنید: App.css
، App.test.js
، serviceWorker.js
و setupTests.js
. بعد ، بیایید همه کدهایی را که به پرونده های حذف شده در ما ارجاع می دهند ، حذف کنیم App.js
.
برای این پروژه ، ما از Open Movie Database API برای بدست آوردن اطلاعات فیلم ، محتوا و تصاویر برنامه خود استفاده خواهیم کرد ، اینجا پیوندی به API است ، برای استفاده از آن برای این برنامه باید کلیدهای دسترسی را ثبت کرده و دریافت کنید ، پس از اتمام کار ، بیایید با ساختن م componentsلفه ها برنامه خود را ادامه دهیم.
اجزای برنامه ساختمان
اول ، در داخل ما src
پوشه را در فهرست پروژه خود ایجاد کنید ، پوشه ای به نام کامپوننت ها ایجاد کنید و در داخل پوشه ، بیایید دو پوشه به نام ایجاد کنیم Movie
و Searchbar
، م componentلفه ما باید مانند تصویر زیر باشد:

م Movieلفه ساخت فیلم
بیایید ساخت Movies
م componentلفه ای ، که ساختار جزئیات فیلم را که از API خود دریافت خواهیم کرد ، مشخص می کند. برای این کار ، داخل Movies
پوشه کامپوننت ما ، یک فایل جدید ایجاد کنید Movie.js
، بعد یک م componentلفه مبتنی بر کلاس برای نتایج API ایجاد کنید ، اجازه دهید این کار را در زیر انجام دهیم.
import React, { Component } from 'react';
import { Card, CardImg, CardText, CardBody, ListGroup, ListGroupItem, Badge } from 'reactstrap';
import styles from './Movie.module.css';
class Movie extends Component{
render(){
if(this.props.movie){
return (
<div className={styles.Movie}>
<h3 className="text-center my-4">
Movie Name: {this.props.movie.Title}
</h3>
<Card className="text-primary bg-dark">
<CardImg className={styles.Img}
top src={this.props.movie.Poster}
alt={this.props.movie.Title}/>
<CardBody>
<ListGroup className="bg-dark">
<ListGroupItem>
<Badge color="primary">Actors:</Badge>
{this.props.movie.Actors}
</ListGroupItem>
<ListGroupItem>
<Badge color="primary">Genre:</Badge>
{this.props.movie.Genre}
</ListGroupItem>
<ListGroupItem>
<Badge color="primary">Year:</Badge>
{this.props.movie.Year}
</ListGroupItem>
<ListGroupItem>
<Badge color="primary">Writer(s):</Badge>
{this.props.movie.Writer}
</ListGroupItem>
<ListGroupItem>
<Badge color="primary">IMDB Rating:</Badge>
{this.props.movie.imdbRating}/10
</ListGroupItem>
</ListGroup>
<CardText className="mt-3 text-white">
<Badge color="secondary">Plot:</Badge>
{this.props.movie.Plot}
</CardText>
</CardBody>
</Card>
</div>
)
}
return null
}
}
export default Movie;
در کد بالا ، استفاده از اجزای موجود در بسته reactstrap
، می توانید اسناد را بررسی کنید اینجا. ما یک م Cardلفه کارت ساخته ایم که شامل نام فیلم ، تصویر ، ژانر ، بازیگر ، سال ، نویسنده فیلم ، رتبه بندی و طرح است. برای سهولت در انتقال داده ها از این م componentلفه ، ما داده ها را به عنوان ابزار دیگری برای سایر ملفه ها ایجاد کردیم. بعد ، بیایید ما را بسازیم Searchbar
جزء.
ساخت کامپوننت نوار جستجو ما
ما Searchbar
کامپوننت دارای یک نوار جستجو و یک جز button دکمه برای جستجوی اجزای فیلم است ، بیایید این کار را در زیر انجام دهیم:
import React from 'react';
import styles from './Searchbar.module.css';
import { connect } from 'react-redux';
import { fetchMovie } from '../../actions';
import Movie from '../Movie/Movie';
class Searchbar extends React.Component{
render(){
return(
<div className={styles.Form}>
<div>
<form onSubmit={this.formHandler}>
<input
type="text"
placeholder="Movie Title"
onChange={e => this.setState({title: e.target.value})}
value={this.state.title}/>
<button type="submit">Search</button>
</form>
</div>
<Movie movie={this.props.movie}/>
</div>
)
}
}
در کد بالا ، ما در حال وارد کردن هستیم connect
از جانب react-redux
که برای اتصال یک جز component React به فروشگاه Redux استفاده می شود ، اطلاعات مربوط به فروشگاه را به جز the ارائه می دهد و همچنین توابع مورد استفاده برای ارسال اقدامات به فروشگاه را فراهم می کند. بعد ، ما وارد کردیم Movie
جز component و یک تابع fetchMovie
از اعمال.
در مرحله بعدی ، ما یک برچسب فرم با یک جعبه ورودی برای ورود عناوین فیلم های خود داریم ، با استفاده از setState
قلاب از React ، ما یک اضافه کردیم onChange
رویداد و مقداری که حالت title
به مقدار وارد شده در جعبه ورودی. ما یک button
برای جستجوی عناوین فیلم و استفاده از Movie
م componentلفه ای که وارد کردیم ، از خصوصیات م componentلفه عبور کردیم props
به نتیجه جستجو.
مورد بعدی برای ما نوشتن تابعی برای ارسال عنوان فیلم خود به API به منظور ارسال نتایج برای ما است ، همچنین باید حالت اولیه برنامه را تنظیم کنیم. بیایید این کار را در زیر انجام دهیم
class Searchbar extends React.Component{
state = {
title: ''
}
formHandler = (event) => {
event.preventDefault();
this.props.fetchMovie(this.state.title);
this.setState({title: ''});
}
در اینجا ، ما حالت اولیه برنامه را روی رشته های خالی تنظیم می کنیم ، یک تابع ایجاد می کنیم formHandler
که یک پارامتر رویداد را می گیرد و fetchMovie
عملکرد از عمل و تنظیم عنوان به عنوان حالت جدید برنامه است. برای تکمیل برنامه ما ، بیایید این م componentلفه را با استفاده از ویژگی connect از صادر کنیم react-redux
، برای انجام این کار ما از redux واکنش استفاده می کنیم mapToStateProps
ویژگی برای انتخاب بخشی از داده مورد نیاز مولفه ما ، می توانید درباره آن بیشتر بیاموزید mapToStateProps
اینجا.
const mapStateToProps = (state) => {
return { movie: state.movie }
}
export default connect(mapStateToProps, { fetchMovie })(Searchbar)
بیایید با ایجاد یک فایل سبک ها را به فرم خود اضافه کنیم Searchbar.module.css
و اضافه کردن سبک های زیر:
.Form{
margin: 3rem auto;
width: 80%;
height: 100%;
}
input{
display: block;
height: 45px;
border: none;
width: 100%;
border-radius: 0.5rem;
outline: none;
padding: 0 1rem;
}
input:focus, select:focus{
border: 2px rgb(16, 204, 179) solid;
}
.Form button{
display: block;
background: rgb(16, 204, 179);
padding: 0.7rem;
border-radius: 0.5rem;
width: 20%;
margin-top: 0.7rem;
color: #FFF;
border: none;
text-decoration: none;
transition: all 0.5s;
}
button:hover{
opacity: 0.6;
}
@media(max-width: 700px){
input{
height: 40px;
padding: 0 1rem;
}
.Form button{
width: 40%;
padding: 0.6rem;
}
}
هنگامی که موارد فوق را انجام دادیم ، مولفه نوار جستجو باید شبیه تصویر زیر باشد:

ایجاد اقدامات برای برنامه
در این بخش ، ما اقدامات Redux را برای برنامه خود تنظیم می کنیم ، ابتدا در داخل src
پوشه را ایجاد کنید actions
و در داخل پوشه ، یک فایل ایجاد می کنیم index.js
فایل. در اینجا ما یک تابع ایجاد می کنیم fetchMovie
که یک پارامتر عنوان را می گیرد و با استفاده از Axios فیلم را از API می گیرد. بیایید این کار را در زیر انجام دهیم:
import axios from 'axios';
export const fetchMovie = (title) =>
async (dispatch) => {
const response = await
axios.get(
`https://cors-anywhere.herokuapp.com/http://www.omdbapi.com/?t=${title}&apikey=APIKEY`);
dispatch({
type: 'FETCH_MOVIE',
payload: response.data
})
}
در کد بالا ، وارد کردیم axios
و تابعی ایجاد کرد به نام fetchMovie
که در می گیرد title
پارامتر را با استفاده از async / انتظار به طوری که بتوانیم از سرور API درخواست کنیم. ما یک dispatch
عملکردی که شی Red عملیاتی را که به Redux منتقل می شود به Redux ارسال می کند. با توجه به آنچه در بالا داریم ، در حال ارسال عملی با نوع هستیم FETCH_MOVIE
و محموله ای که شامل پاسخی است که از API دریافت کرده ایم.
توجه داشته باشید: apikey
در درخواست با درخواست شما جایگزین خواهد شد apikey
پس از ثبت نام در OmdbAPI.
ایجاد برنامه های کاهش دهنده برنامه
در این بخش ، ما می خواهیم کاهنده هایی برای برنامه خود ایجاد کنیم.
const fetchMovieReducer = (state = null, action) => {
switch(action.type){
case 'FETCH_MOVIE':
return action.payload;
default:
return state;
}
}
const rootReducer = (state, action) => {
return {
movie: fetchMovieReducer(state, action)
}
}
export default rootReducer;
در کد بالا ، ما یک ایجاد کردیم fetchMovieReducer
که در حالت پیش فرض null
و یک action
پارامتر ، با استفاده از یک عملگر سوئیچ ، برای مورد FETCH_MOVIE
ما مقدار action.payload
که فیلمی است که از API گرفتیم. اگر عملی که سعی کردیم انجام دهیم در کاهنده نیست ، پس حالت پیش فرض خود را برمی گردانیم.
بعد ، ما یک ایجاد کردیم rootReducer
تابعی که وضعیت فعلی و یک عمل را به عنوان ورودی بپذیرد و بازگرداند fetchMovieReducer
.
با هم قرار دادن آن
در این بخش ، ما می خواهیم برنامه خود را با ایجاد فروشگاه redux خود در index.js
، بیایید این کار را در زیر انجام دهیم:
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import App from './App';
import 'bootstrap/dist/css/bootstrap.min.css';
import './index.css';
import reducers from './reducers';
const store = createStore(reducers, applyMiddleware(thunk))
ReactDOM.render(
<Provider store={store}>
<>
<App/>
</>
</Provider>,
document.getElementById('root')
)
در کد بالا ، ما برنامه را ایجاد کردیم store
با استفاده از createStore
روش با عبور از کاهنده ای که ایجاد کردیم و یک میان افزار. میان افزارها افزودنیهایی هستند که به ما امکان می دهد عملکرد Redux را ارتقا دهیم. در اینجا ما با استفاده از Redux Thunk میان افزار با استفاده از applyMiddleware
. میان افزار Redux Thunk برای انجام به روزرسانی های همزمان به فروشگاه ما ضروری است. این مورد لازم است زیرا به طور پیش فرض ، Redux فروشگاه را به طور همزمان به روز می کند.
برای اطمینان از اینکه برنامه ما فروشگاه دقیق استفاده را می داند ، برنامه خود را در یک بسته بندی کردیم Provider
جز component و فروشگاه را به عنوان یک وسیله نقلیه عبور داد ، با این کار سایر اجزای برنامه ما می توانند اطلاعات را با فروشگاه متصل و به اشتراک بگذارند.
بیایید کمی سبک به سبک خود اضافه کنیم index.css
فایل.
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
body{
background: rgb(15, 10, 34);
color: #FFF;
height: 100vh;
max-width: 100%;
}
ارائه و آزمایش جزئیات یاب فیلم
در این بخش ، ما می خواهیم با ارائه برنامه خود در برنامه ، برنامه خود را به نتیجه برسانیم App.js
، برای انجام این کار ، بیایید یک جز component کلاس محور به نام ایجاد کنیم App
و نوار جستجو و قسمت ورودی خود را مقدار دهی اولیه کنید.
import React from 'react';
import Searchbar from './components/Searchbar/Searchbar';
import styles from './App.module.css';
class App extends React.Component{
render(){
return(
<div className={styles.App}>
<h1 className={styles.Title}>Movies Search App</h1>
<Searchbar/>
</div>
)
}
}
export default App;
در اینجا ، ما یک م Appلفه مبتنی بر کلاس برنامه با یک ایجاد کردیم h1
که می گوید برنامه جستجوی فیلم و ما اضافه شده است Searchbar
جزء. برنامه ما باید مانند تصویر زیر باشد:

نسخه آزمایشی فعال در Codesandbox در دسترس است.
نتیجه
گیرنده ها بخش مهمی از مدیریت دولت Redux هستند ، با كاهش دهنده ها می توانیم توابع خالصی را برای به روز كردن مناطق خاص برنامه های Redux خود بدون عوارض جانبی بنویسیم. ما اصول کاهنده های Redux ، کاربردهای آنها و مفهوم اصلی گیرنده ها ، حالت و استدلال ها را یاد گرفته ایم.
با مشاهده مستندات مربوط به گیربکس های Redux می توانید این کار را بیشتر ادامه دهید اینجا. می توانید این کار را بیشتر ادامه دهید و بیشتر بر روی گیربکس های Redux بسازید ، به من اطلاع دهید چه چیزی را می سازید.
منابع
