console
const CcFragment = cc.CcFragment;
cc.startup(
{
isModuleMode: true,
store: {
counter: {
num1: 0,
num2: 0,
}
},
reducer: {
counter: {
incNum1({ moduleState }) {
return { num1: moduleState.num1 + 1 };
},
async incNum2({moduleState}) {
return { num2: moduleState.num2 + 1 };
},
decNum1({ moduleState }) {
return { num1: moduleState.num1 - 1 };
},
decNum2( {moduleState }) {
return { num2: moduleState.num2 - 1 };
}
},
foo: {
incNum1AndNum2({ moduleState }) {
const { num1, num2 } = moduleState;
return { num1: num1 + 1, num2: num2 + 1 };
},
async incNum1AndNum2Wow({ dispatch }) {
dispatch('counter/incNum1');
dispatch('counter/incNum2');
}
}
}
}
);
function incNum1(num1) {
return { num1 };
}
async function incNum2(executionContext, sentence) {
const { moduleState, dispatch, effect, xeffect } = executionContext;
return { num1: moduleState.num1 + 1 };
}
class Counter extends React.Component {
$$computed(){
return{
num1(num1){
return num1*100;
}
}
}
incNum1ByClassicalSetState = () => {
this.setState({ num1: this.state.num1 + 1 });
}
incNum1ByDispatch = () => {
this.$$dispatch('incNum1');
}
incNum1ByCustomFunction1 = () => {
this.$$effect('counter', incNum1, this.state.num1 + 1);
}
incNum1ByCustomFunction2 = () => {
this.$$xeffect('counter', incNum2, `xffect will use custom function's first param to inject executionContext `);
}
incNum1ByInvoke = () => {
this.$$invoke(incNum1, this.state.num1 + 1);
}
render() {
const { num1, num2 } = this.state;
const { num1:scaledNum1 } = this.$$refComputed;
return (
<div>
<span>scaledNum1 is {scaledNum1}</span>
<hr />
<span>num1 is {num1}</span>
<hr />
<span>num2 is {num2}</span>
<hr />
<button onClick={this.incNum1ByClassicalSetState}>inc num1 by classical setState</button>
<button onClick={this.incNum1ByDispatch}>inc num1 by dispatch</button>
<button data-cct="incNum1" onClick={this.$$domDispatch}>inc num1 by domDispatch</button>
<button onClick={this.incNum1ByCustomFunction1}>inc num1 by custom function 1</button>
<button onClick={this.incNum1ByCustomFunction2}>inc num1 by custom function 2</button>
<button onClick={this.incNum1ByInvoke}>inc num1 by custom function 2</button>
{/*
here we use $$domDispatch,
data-cct means action type,
data-ccrm means reducer module name, if we don't specify it,
cc will use current instance's module name to be reducer module name,
and current instance belong to counter module, but we haven't defined a function named incNum1AndNum2 in counter reducer,
so we have to write data-ccrm="foo",
by the way, data-ccm means module,
and we needn't write data-ccm="counter", because current instance belong to counter module, only if we want to change other
module's state we have to write a module name in data-ccm
*/}
<button data-cct="incNum1AndNum2" data-ccrm="foo" onClick={this.$$domDispatch}>inc num1 and num2 both</button>
<button data-cct="incNum1AndNum2Wow" data-ccrm="foo" onClick={this.$$domDispatch}>inc num1 and num2 both in another way</button>
{/*
all cc insntance can communicate with emit&on or emitIdentity&onIdentity
*/}
<button onClick={()=>this.$$emit('hi', 'param1', 'param2')}>emitToApp</button>
<button onClick={()=>this.$$emitIdentity('hi2', 'identity', 'Iparam1', 'Iparam2')}>emitIdentityToApp</button>
</div>
);
}
}
const CcCounter = cc.register('Counter', { module: 'counter', sharedStateKeys: '*' })(Counter);
class App extends React.Component {
constructor(props, context) {
super(props, context);
this.state = { showCounter: true };
}
componentDidMount(){
this.$$on('hi',(p1, p2)=>alert(`p1${p1} p2${p2}`));
this.$$onIdentity('hi2','identity',(p1, p2)=>alert(`p1${p1} p2${p2}`))
}
render() {
return (
<div>
<div style={{border:'6px solid red', padding:'8px'}}>
here show cc's hook
<CcFragment connect={{'counter/*':''}} render={({hook, propState})=>{
const [count, setCount] = hook.useState(0);
return (
<div>
<span style={{color:'purple', paddingRight:'12px'}}>counter.num1: {propState.counter.num1}</span>
<button onClick={()=>setCount(count+1)}>add, now is:{count}</button>
<button onClick={()=>setCount(count-1)}>minus, now is:{count}</button>
</div>
);
}}/>
</div>
{/* let Counter unmount and mount again, to show their state will been recovered by cc from cc store */}
<button onClick={()=>this.setState({showCounter:!this.state.showCounter})}>toggle counter view</button>
{/* initialize 3 CcCounter, to show their state will sync from each other by cc */}
{
this.state.showCounter ?
<React.Fragment>
<CcCounter />
<CcCounter />
<CcCounter />
</React.Fragment> :
''
}
</div>
);
}
}
const CcApp = cc.register('App')(App);
ReactDOM.render(<CcApp />, document.getElementById('app'))
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>
react.js 练习模板
</title>
<script crossorigin src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js">
</script>
<script crossorigin src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js">
</script>
<script src="https://www.zzkai.com/js/react-control-center-1.1.74.min.js">
</script>
</head>
<body>
<div id="app">
</div>
</body>
</html>