مدیریت پیشرفتهی حالت در React با Redux و Mobx - قسمت هشتم - تنظیمات پروژههای React برای کار با Mobx decorators
نویسنده: وحید نصیری
تاریخ: ۱۳۹۸/۱۰/۲۲ ۸:۵
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
import { decorate } from "mobx";
class Count {
value = 0;
}
decorate(Count, { value: observable });
const count = new Count(); const text = observable({
value: "Hello world!",
get uppercase() {
return this.value.toUpperCase();
}
}); > create-react-app state-management-with-mobx-part3 > cd state-management-with-mobx-part3 > npm start
> npm install --save mobx
<!DOCTYPE html>
<html lang="en">
<head>
<title>MobX Basics, part 3</title>
<meta charset="UTF-8" />
<link href="src/styles.css" />
</head>
<body>
<main>
<input id="text-input" />
<p id="text-display"></p>
<p id="text-display-uppercase"></p>
</main>
<script src="src/index.js"></script>
</body>
</html> import { autorun, computed, observable } from "mobx";
const input = document.getElementById("text-input");
const textDisplay = document.getElementById("text-display");
const loudDisplay = document.getElementById("text-display-uppercase");
class Text {
@observable value = "Hello World";
@computed get uppercase() {
return this.value.toUpperCase();
}
}
const text = new Text();
input.addEventListener("keyup", event => {
text.value = event.target.value;
});
autorun(() => {
input.value = text.value;
textDisplay.textContent = text.value;
loudDisplay.textContent = text.uppercase;
}); ./src/index.js
SyntaxError: \src\index.js: Support for the experimental syntax 'decorators-legacy' isn't currently enabled (8:3):
6 |
7 | class Text {
> 8 | @observable value = "Hello World";
| ^
9 | @computed get uppercase() {
10 | return this.value.toUpperCase();
11 | } import { observable, computed, action } from "mobx";
class Timer {
@observable start = Date.now();
@observable current = Date.now();
@computed
get elapsedTime() {
return this.current - this.start + "milliseconds";
}
@action
tick() {
this.current = Date.now();
}
} import { observable, computed, action, decorate } from "mobx";
class Timer {
start = Date.now();
current = Date.now();
get elapsedTime() {
return this.current - this.start + "milliseconds";
}
tick() {
this.current = Date.now();
}
}
decorate(Timer, {
start: observable,
current: observable,
elapsedTime: computed,
tick: action
}); const Counter = observer(({ count }) => {
return (
// ...
);
}); > create-react-app my-proj1 --typescript
{
"compilerOptions": {
// ...
"experimentalDecorators": true
}
} > npm i --save-dev customize-cra react-app-rewired
const {
override,
addDecoratorsLegacy,
disableEsLint
} = require("customize-cra");
module.exports = override(
// enable legacy decorators babel plugin
addDecoratorsLegacy(),
// disable eslint in webpack
disableEsLint()
); "scripts": {
"start": "react-app-rewired start",
"build": "react-app-rewired build",
"test": "react-app-rewired test",
"eject": "react-app-rewired eject"
}, {
"extends": "react-app",
"parserOptions": {
"ecmaFeatures": {
"legacyDecorators": true
}
}
} {
"env": {
"node": true,
"commonjs": true,
"browser": true,
"es6": true,
"mocha": true
},
"settings": {
"react": {
"version": "detect"
}
},
"parserOptions": {
"ecmaFeatures": {
"jsx": true,
"legacyDecorators": true
},
"ecmaVersion": 2018,
"sourceType": "module"
},
"plugins": [
"babel",
"react",
"react-hooks",
"react-redux",
"no-async-without-await",
"css-modules",
"filenames",
"simple-import-sort"
],
"rules": {
"no-const-assign": "warn",
"no-this-before-super": "warn",
"constructor-super": "warn",
"strict": [
"error",
"safe"
],
"no-debugger": "error",
"brace-style": [
"error",
"1tbs",
{
"allowSingleLine": true
}
],
"no-trailing-spaces": "error",
"keyword-spacing": "error",
"space-before-function-paren": [
"error",
"never"
],
"spaced-comment": [
"error",
"always"
],
"vars-on-top": "error",
"no-undef": "error",
"no-undefined": "warn",
"comma-dangle": [
"error",
"never"
],
"quotes": [
"error",
"double"
],
"semi": [
"error",
"always"
],
"guard-for-in": "error",
"no-eval": "error",
"no-with": "error",
"valid-typeof": "error",
"no-unused-vars": "error",
"no-continue": "warn",
"no-extra-semi": "warn",
"no-unreachable": "warn",
"no-unused-expressions": "warn",
"max-len": [
"warn",
80,
4
],
"react/prefer-es6-class": "warn",
"react/jsx-boolean-value": "warn",
"react-hooks/rules-of-hooks": "error",
"react-hooks/exhaustive-deps": "warn",
"react/prop-types": "off",
"react-redux/mapDispatchToProps-returns-object": "off",
"react-redux/prefer-separate-component-file": "off",
"no-async-without-await/no-async-without-await": "warn",
"css-modules/no-undef-class": "off",
"filenames/match-regex": [
"off",
"^[a-zA-Z]+\\.*\\b(typescript|module|locale|validate|test|action|api|reducer|saga)?\\b$",
true
],
"filenames/match-exported": "off",
"filenames/no-index": "off",
"simple-import-sort/sort": "error"
},
"extends": [
"react-app",
"eslint:recommended",
"plugin:react/recommended",
"plugin:react-redux/recommended",
"plugin:css-modules/recommended"
],
"globals": {
"Atomics": "readonly",
"SharedArrayBuffer": "readonly",
"process": true
}
} >npm i --save-dev eslint babel-eslint eslint-config-react-app eslint-loader eslint-plugin-babel eslint-plugin-react eslint-plugin-css-modules eslint-plugin-filenames eslint-plugin-flowtype eslint-plugin-import eslint-plugin-no-async-without-await eslint-plugin-react-hooks eslint-plugin-react-redux eslint-plugin-redux-saga eslint-plugin-simple-import-sort eslint-loader typescript
const {
override,
addDecoratorsLegacy,
useEslintRc
} = require("customize-cra");
module.exports = override(
addDecoratorsLegacy(),
useEslintRc(".eslintrc.json")
); Experimental support for decorators is a feature that is subject to change in a future release. Set the 'experimentalDecorators' option in your 'tsconfig' or 'jsconfig' to remove this warning.ts(1219)
{
"compilerOptions": {
"experimentalDecorators": true,
"allowJs": true
}
}