use-agent-reducer
v14.7.0
Published
the purpose of this project is make useReducer classify
Downloads
22
Maintainers
Readme
use-agent-reducer
other language: 中文
agent-reducer is a very powerful tool, it converts a model object (OriginAgent
) to be a state changeable object (Agent
). It is designed on the reducer running base. Every thing returned from an Agent
method will be a next state.
use-agent-reducer
is designed for using agent-reducer
in react hooks environment。
We can compare a classify reducer with agent-reducer
model.
import {OriginAgent} from "agent-reducer";
interface Action {
type?: 'stepUp' | 'stepDown' | 'step' | 'sum',
payload?: number[] | boolean
}
/**
* classify reducer
* @param state
* @param action
*/
const countReducer = (state: number = 0, action: Action = {}): number => {
switch (action.type) {
case "stepDown":
return state - 1;
case "stepUp":
return state + 1;
case "step":
return state + (action.payload ? 1 : -1);
case "sum":
return state + (Array.isArray(action.payload) ?
action.payload : []).reduce((r, c): number => r + c, 0);
default:
return state;
}
}
/**
* agent-reducer model
*/
class CountAgent implements OriginAgent<number> {
state = 0;
stepUp(): number {
return this.state + 1;
}
stepDown = (): number => this.state - 1;
step = (isUp: boolean) => isUp ? this.stepUp() : this.stepDown();
sum(...counts: number[]): number {
return this.state + counts.reduce((r, c): number => r + c, 0);
};
}
The code below is designed for a count change model, we can call method from CountAgent
instance, and make every return to be a next state, this running mode is similar with reducer working mode, but more simple.
use useAgentReducer
to replace useReducer
.
import React,{memo} from 'react';
import {OriginAgent} from "agent-reducer";
import {useAgentReducer} from 'use-agent-reducer';
/**
* model class
*/
class CountAgent implements OriginAgent<number> {
state = 0;
// increase state by 1
stepUp(): number{
return this.state + 1;
}
// decrease state by 1
stepDown = (): number => this.state - 1;
step = (isUp: boolean) => isUp ? this.stepUp() : this.stepDown();
sum(...counts: number[]): number {
return this.state + counts.reduce((r, c): number => r + c, 0);
};
}
export const Counter = memo(() => {
// useAgentReducer returns an `Agent` object,
// which is the agent of model CountAgent.
// we can get state and other property values from it.
const {state,stepUp,stepDown} = useAgentReducer(CountAgent);
return (
<div>
<button onClick={stepUp}>stepUp</button>
<span>{state}</span>
<button onClick={stepDown}>stepDown</button>
</div>
);
});
The code below shows how to use API useAgentReducer
with OriginAgent
model, there are some concepts and designs about agent-reducer
you should know first, you can learn these from agent-reducer, then you will know what can be a model and why after reassign Agent
method (stepUp
) into another object, keyword this
still represent Agent
when the method is running.
As agent-reducer
is designed by taking a next state from an Agent
method return, we can not take a promise resolve data to be next state, but we can use MiddleWare
in agent-reducer
to reproduce a promise object, and take its resolve data as next state.
import React,{memo,useEffect} from 'react';
import {middleWare,MiddleWarePresets, OriginAgent} from "agent-reducer";
import {useAgent} from 'use-agent-reducer';
/**
* model
*/
class CountAgent implements OriginAgent<number> {
state = 0;
stepUp = (): number => this.state + 1;
stepDown = (): number => this.state - 1;
step = (isUp: boolean) => isUp ? this.stepUp() : this.stepDown();
sum = (...counts: number[]): number => {
return this.state + counts.reduce((r, c): number => r + c, 0);
};
// return promise will change the state to be a promise object,
// use MiddleWarePresets.takePromiseResolve(),
// can take the promise resolve value to be next state
@middleWare(MiddleWarePresets.takePromiseResolve())
async requestAdditions(){
const args = await Promise.resolve([1,2,3]);
return this.sum(...args);
}
}
export const Counter = memo(() => {
const {state,stepUp,stepDown,requestActions}=useAgent(CountAgent);
useEffect(()=>{
requestActions();
},[]);
return (
<div>
<button onClick={stepUp}>stepUp</button>
<span>{state}</span>
<button onClick={stepDown}>stepDown</button>
</div>
);
});
If you want to know more about useAgentReducer
, check document here.