diff --git a/04-frameworks/01-react/03-react-hooks/06-ajax-field-change/.babelrc b/04-frameworks/01-react/03-react-hooks/06-ajax-field-change/.babelrc deleted file mode 100644 index 469d3d55f..000000000 --- a/04-frameworks/01-react/03-react-hooks/06-ajax-field-change/.babelrc +++ /dev/null @@ -1,7 +0,0 @@ -{ - "presets": [ - "@babel/preset-env", - "@babel/preset-typescript", - "@babel/preset-react" - ] -} diff --git a/04-frameworks/01-react/03-react-hooks/06-ajax-field-change/Readme.md b/04-frameworks/01-react/03-react-hooks/06-ajax-field-change/Readme.md index b7789b8e5..27078f513 100644 --- a/04-frameworks/01-react/03-react-hooks/06-ajax-field-change/Readme.md +++ b/04-frameworks/01-react/03-react-hooks/06-ajax-field-change/Readme.md @@ -1,6 +1,6 @@ # 06 Ajax field change -## Resume +## Summary This example takes as a starting point the example \ \_05-component-update-render. @@ -16,7 +16,7 @@ As a bonus, we will check how to use Debounce (wait a little until the user stop npm install ``` -- Let's open the _demo.js_, and let's add an entry in the state that stores the current search filter, and another state in which we +- Let's open the _demo.tsx_, and let's add an entry in the state that stores the current search filter, and another state in which we are going to store a list of users. _./src/demo.tsx_ diff --git a/04-frameworks/01-react/03-react-hooks/06-ajax-field-change/Readme_es.md b/04-frameworks/01-react/03-react-hooks/06-ajax-field-change/Readme_es.md index 6e0d253f3..4fecef354 100644 --- a/04-frameworks/01-react/03-react-hooks/06-ajax-field-change/Readme_es.md +++ b/04-frameworks/01-react/03-react-hooks/06-ajax-field-change/Readme_es.md @@ -21,7 +21,7 @@ así llamadas innecesarias). npm install ``` -- Vamos abrir el fichero _demo.js_ y vamos añadir una entrada en el +- Vamos abrir el fichero _demo.tsx_ y vamos añadir una entrada en el estado que almacene el filtro actual de busqueda, y otra en la que almacene una lista de usuarios. diff --git a/04-frameworks/01-react/03-react-hooks/07-custom-hook/src/index.html b/04-frameworks/01-react/03-react-hooks/06-ajax-field-change/index.html similarity index 54% rename from 04-frameworks/01-react/03-react-hooks/07-custom-hook/src/index.html rename to 04-frameworks/01-react/03-react-hooks/06-ajax-field-change/index.html index a3d74b719..892c75140 100644 --- a/04-frameworks/01-react/03-react-hooks/07-custom-hook/src/index.html +++ b/04-frameworks/01-react/03-react-hooks/06-ajax-field-change/index.html @@ -1,12 +1,12 @@ - - - - My App Example + + + React App - React hooks
+ diff --git a/04-frameworks/01-react/03-react-hooks/06-ajax-field-change/package.json b/04-frameworks/01-react/03-react-hooks/06-ajax-field-change/package.json index d434b896c..cb10a2306 100644 --- a/04-frameworks/01-react/03-react-hooks/06-ajax-field-change/package.json +++ b/04-frameworks/01-react/03-react-hooks/06-ajax-field-change/package.json @@ -1,40 +1,24 @@ { - "name": "react-example", - "version": "1.0.0", - "description": "", - "main": "index.js", + "name": "hello-vite", + "private": true, + "version": "0.0.0", + "type": "module", "scripts": { - "start": "run-p -l type-check:watch start:dev", - "type-check": "tsc --noEmit", - "type-check:watch": "npm run type-check -- --watch", - "start:dev": "webpack-dev-server --mode development --open", - "build": "rimraf dist && webpack --mode development" + "start": "vite --host", + "build": "vite build", + "preview": "vite preview" }, - "author": "", - "license": "ISC", "devDependencies": { - "@babel/cli": "^7.17.10", - "@babel/core": "^7.17.10", - "@babel/preset-env": "^7.17.10", - "@babel/preset-react": "^7.17.12", - "@babel/preset-typescript": "^7.16.7", - "@types/react": "^18.0.9", - "@types/react-dom": "^18.0.4", - "babel-loader": "^8.2.5", - "css-loader": "^6.7.1", - "html-loader": "^3.1.0", - "html-webpack-plugin": "^5.5.0", - "npm-run-all": "^4.1.5", - "rimraf": "^3.0.2", - "style-loader": "^3.3.1", - "typescript": "^4.6.4", - "webpack": "^5.72.1", - "webpack-cli": "^4.9.2", - "webpack-dev-server": "^4.9.0" + "@types/react": "^19.1.8", + "@types/react-dom": "^19.1.6", + "@vitejs/plugin-react": "^4.6.0", + "typescript": "^5.8.3", + "vite": "^7.0.4", + "vite-plugin-checker": "^0.10.0" }, "dependencies": { - "react": "^18.1.0", - "react-dom": "^18.1.0", - "use-debounce": "^8.0.1" + "react": "^19.1.0", + "react-dom": "^19.1.0", + "use-debounce": "^10.0.5" } } diff --git a/04-frameworks/01-react/03-react-hooks/06-ajax-field-change/tsconfig.json b/04-frameworks/01-react/03-react-hooks/06-ajax-field-change/tsconfig.json index 3312b5f1e..a057cea1d 100644 --- a/04-frameworks/01-react/03-react-hooks/06-ajax-field-change/tsconfig.json +++ b/04-frameworks/01-react/03-react-hooks/06-ajax-field-change/tsconfig.json @@ -1,18 +1,19 @@ { "compilerOptions": { - "target": "es6", - "module": "es6", - "moduleResolution": "node", - "declaration": false, + "esModuleInterop": true, + "isolatedModules": true, + "jsx": "react-jsx", + "lib": ["ESNext", "DOM"], + "module": "ESNext", + "moduleResolution": "bundler", + "noEmit": true, "noImplicitAny": false, - "allowSyntheticDefaultImports": true, - "sourceMap": true, - "jsx": "react", - "noLib": false, - "suppressImplicitAnyIndexErrors": true, + "noImplicitReturns": true, + "resolveJsonModule": true, "skipLibCheck": true, - "esModuleInterop": true + "sourceMap": true, + "target": "ESNext", + "useDefineForClassFields": true }, - "include": ["src/**/*"], - "exclude": ["node_modules"] + "include": ["src"] } diff --git a/04-frameworks/01-react/03-react-hooks/06-ajax-field-change/vite.config.ts b/04-frameworks/01-react/03-react-hooks/06-ajax-field-change/vite.config.ts new file mode 100644 index 000000000..a0024d88e --- /dev/null +++ b/04-frameworks/01-react/03-react-hooks/06-ajax-field-change/vite.config.ts @@ -0,0 +1,7 @@ +import { defineConfig } from "vite"; +import checker from "vite-plugin-checker"; +import react from "@vitejs/plugin-react"; + +export default defineConfig({ + plugins: [checker({ typescript: true }), react()], +}); diff --git a/04-frameworks/01-react/03-react-hooks/06-ajax-field-change/webpack.config.js b/04-frameworks/01-react/03-react-hooks/06-ajax-field-change/webpack.config.js deleted file mode 100644 index 326060f82..000000000 --- a/04-frameworks/01-react/03-react-hooks/06-ajax-field-change/webpack.config.js +++ /dev/null @@ -1,54 +0,0 @@ -const HtmlWebpackPlugin = require("html-webpack-plugin"); -const path = require("path"); -const basePath = __dirname; - -module.exports = { - context: path.join(basePath, "src"), - resolve: { - extensions: [".js", ".ts", ".tsx"], - }, - entry: { - app: ["./index.tsx", "./styles.css"], - }, - devtool: "eval-source-map", - stats: "errors-only", - output: { - filename: "[name].[chunkhash].js", - }, - module: { - rules: [ - { - test: /\.tsx?$/, - exclude: /node_modules/, - loader: "babel-loader", - }, - { - test: /\.(png|jpg)$/, - type: "asset/resource", - }, - { - test: /\.html$/, - loader: "html-loader", - }, - { - test: /\.css$/, - exclude: /node_modules/, - use: [ - { - loader: "style-loader", - }, - { - loader: "css-loader", - }, - ], - }, - ], - }, - plugins: [ - //Generate index.html in /dist => https://github.com/ampedandwired/html-webpack-plugin - new HtmlWebpackPlugin({ - filename: "index.html", //Name of file in ./dist/ - template: "index.html", //Name of template in ./src - }), - ], -}; diff --git a/04-frameworks/01-react/03-react-hooks/07-custom-hook/.babelrc b/04-frameworks/01-react/03-react-hooks/07-custom-hook/.babelrc deleted file mode 100644 index 469d3d55f..000000000 --- a/04-frameworks/01-react/03-react-hooks/07-custom-hook/.babelrc +++ /dev/null @@ -1,7 +0,0 @@ -{ - "presets": [ - "@babel/preset-env", - "@babel/preset-typescript", - "@babel/preset-react" - ] -} diff --git a/04-frameworks/01-react/03-react-hooks/07-custom-hook/Readme.md b/04-frameworks/01-react/03-react-hooks/07-custom-hook/Readme.md index b7cc0439c..b139eabc3 100644 --- a/04-frameworks/01-react/03-react-hooks/07-custom-hook/Readme.md +++ b/04-frameworks/01-react/03-react-hooks/07-custom-hook/Readme.md @@ -1,8 +1,8 @@ # 07 Custom hooks -## Resume +## Summary -This example takes as its starting point the \ _06-ajax-field-change example. +This example takes as its starting point the _06-ajax-field-change_ example. Hooks are cool, but our functional component seems to get cluttered, is there a way to extract functionality outside the functional component? @@ -53,7 +53,7 @@ export const MyComponent = () => { A. Encapsulating as well the _UseEffect_ -_./src/demo.js_ +_./src/demo.tsx_ ```diff import React from "react"; diff --git a/04-frameworks/01-react/03-react-hooks/06-ajax-field-change/src/index.html b/04-frameworks/01-react/03-react-hooks/07-custom-hook/index.html similarity index 54% rename from 04-frameworks/01-react/03-react-hooks/06-ajax-field-change/src/index.html rename to 04-frameworks/01-react/03-react-hooks/07-custom-hook/index.html index a3d74b719..892c75140 100644 --- a/04-frameworks/01-react/03-react-hooks/06-ajax-field-change/src/index.html +++ b/04-frameworks/01-react/03-react-hooks/07-custom-hook/index.html @@ -1,12 +1,12 @@ - - - - My App Example + + + React App - React hooks
+ diff --git a/04-frameworks/01-react/03-react-hooks/07-custom-hook/package.json b/04-frameworks/01-react/03-react-hooks/07-custom-hook/package.json index d434b896c..cb10a2306 100644 --- a/04-frameworks/01-react/03-react-hooks/07-custom-hook/package.json +++ b/04-frameworks/01-react/03-react-hooks/07-custom-hook/package.json @@ -1,40 +1,24 @@ { - "name": "react-example", - "version": "1.0.0", - "description": "", - "main": "index.js", + "name": "hello-vite", + "private": true, + "version": "0.0.0", + "type": "module", "scripts": { - "start": "run-p -l type-check:watch start:dev", - "type-check": "tsc --noEmit", - "type-check:watch": "npm run type-check -- --watch", - "start:dev": "webpack-dev-server --mode development --open", - "build": "rimraf dist && webpack --mode development" + "start": "vite --host", + "build": "vite build", + "preview": "vite preview" }, - "author": "", - "license": "ISC", "devDependencies": { - "@babel/cli": "^7.17.10", - "@babel/core": "^7.17.10", - "@babel/preset-env": "^7.17.10", - "@babel/preset-react": "^7.17.12", - "@babel/preset-typescript": "^7.16.7", - "@types/react": "^18.0.9", - "@types/react-dom": "^18.0.4", - "babel-loader": "^8.2.5", - "css-loader": "^6.7.1", - "html-loader": "^3.1.0", - "html-webpack-plugin": "^5.5.0", - "npm-run-all": "^4.1.5", - "rimraf": "^3.0.2", - "style-loader": "^3.3.1", - "typescript": "^4.6.4", - "webpack": "^5.72.1", - "webpack-cli": "^4.9.2", - "webpack-dev-server": "^4.9.0" + "@types/react": "^19.1.8", + "@types/react-dom": "^19.1.6", + "@vitejs/plugin-react": "^4.6.0", + "typescript": "^5.8.3", + "vite": "^7.0.4", + "vite-plugin-checker": "^0.10.0" }, "dependencies": { - "react": "^18.1.0", - "react-dom": "^18.1.0", - "use-debounce": "^8.0.1" + "react": "^19.1.0", + "react-dom": "^19.1.0", + "use-debounce": "^10.0.5" } } diff --git a/04-frameworks/01-react/03-react-hooks/07-custom-hook/src/app.tsx b/04-frameworks/01-react/03-react-hooks/07-custom-hook/src/app.tsx index bc2cf5bd8..363d30bfa 100644 --- a/04-frameworks/01-react/03-react-hooks/07-custom-hook/src/app.tsx +++ b/04-frameworks/01-react/03-react-hooks/07-custom-hook/src/app.tsx @@ -3,4 +3,4 @@ import { MyComponent } from "./demo"; export const App = () => { return ; -}; +}; \ No newline at end of file diff --git a/04-frameworks/01-react/03-react-hooks/07-custom-hook/tsconfig.json b/04-frameworks/01-react/03-react-hooks/07-custom-hook/tsconfig.json index 3312b5f1e..a057cea1d 100644 --- a/04-frameworks/01-react/03-react-hooks/07-custom-hook/tsconfig.json +++ b/04-frameworks/01-react/03-react-hooks/07-custom-hook/tsconfig.json @@ -1,18 +1,19 @@ { "compilerOptions": { - "target": "es6", - "module": "es6", - "moduleResolution": "node", - "declaration": false, + "esModuleInterop": true, + "isolatedModules": true, + "jsx": "react-jsx", + "lib": ["ESNext", "DOM"], + "module": "ESNext", + "moduleResolution": "bundler", + "noEmit": true, "noImplicitAny": false, - "allowSyntheticDefaultImports": true, - "sourceMap": true, - "jsx": "react", - "noLib": false, - "suppressImplicitAnyIndexErrors": true, + "noImplicitReturns": true, + "resolveJsonModule": true, "skipLibCheck": true, - "esModuleInterop": true + "sourceMap": true, + "target": "ESNext", + "useDefineForClassFields": true }, - "include": ["src/**/*"], - "exclude": ["node_modules"] + "include": ["src"] } diff --git a/04-frameworks/01-react/03-react-hooks/07-custom-hook/vite.config.ts b/04-frameworks/01-react/03-react-hooks/07-custom-hook/vite.config.ts new file mode 100644 index 000000000..a0024d88e --- /dev/null +++ b/04-frameworks/01-react/03-react-hooks/07-custom-hook/vite.config.ts @@ -0,0 +1,7 @@ +import { defineConfig } from "vite"; +import checker from "vite-plugin-checker"; +import react from "@vitejs/plugin-react"; + +export default defineConfig({ + plugins: [checker({ typescript: true }), react()], +}); diff --git a/04-frameworks/01-react/03-react-hooks/07-custom-hook/webpack.config.js b/04-frameworks/01-react/03-react-hooks/07-custom-hook/webpack.config.js deleted file mode 100644 index 326060f82..000000000 --- a/04-frameworks/01-react/03-react-hooks/07-custom-hook/webpack.config.js +++ /dev/null @@ -1,54 +0,0 @@ -const HtmlWebpackPlugin = require("html-webpack-plugin"); -const path = require("path"); -const basePath = __dirname; - -module.exports = { - context: path.join(basePath, "src"), - resolve: { - extensions: [".js", ".ts", ".tsx"], - }, - entry: { - app: ["./index.tsx", "./styles.css"], - }, - devtool: "eval-source-map", - stats: "errors-only", - output: { - filename: "[name].[chunkhash].js", - }, - module: { - rules: [ - { - test: /\.tsx?$/, - exclude: /node_modules/, - loader: "babel-loader", - }, - { - test: /\.(png|jpg)$/, - type: "asset/resource", - }, - { - test: /\.html$/, - loader: "html-loader", - }, - { - test: /\.css$/, - exclude: /node_modules/, - use: [ - { - loader: "style-loader", - }, - { - loader: "css-loader", - }, - ], - }, - ], - }, - plugins: [ - //Generate index.html in /dist => https://github.com/ampedandwired/html-webpack-plugin - new HtmlWebpackPlugin({ - filename: "index.html", //Name of file in ./dist/ - template: "index.html", //Name of template in ./src - }), - ], -}; diff --git a/04-frameworks/01-react/03-react-hooks/08-pure-component/.babelrc b/04-frameworks/01-react/03-react-hooks/08-pure-component/.babelrc deleted file mode 100644 index 469d3d55f..000000000 --- a/04-frameworks/01-react/03-react-hooks/08-pure-component/.babelrc +++ /dev/null @@ -1,7 +0,0 @@ -{ - "presets": [ - "@babel/preset-env", - "@babel/preset-typescript", - "@babel/preset-react" - ] -} diff --git a/04-frameworks/01-react/03-react-hooks/08-pure-component/Readme_es.md b/04-frameworks/01-react/03-react-hooks/08-pure-component/Readme_es.md index 37180b4b8..fa2004f5d 100644 --- a/04-frameworks/01-react/03-react-hooks/08-pure-component/Readme_es.md +++ b/04-frameworks/01-react/03-react-hooks/08-pure-component/Readme_es.md @@ -17,7 +17,7 @@ Vamos a ello. npm install ``` -- Vamos a pegar un ejemplo en _demo.js_, este código va tener dos +- Vamos a pegar un ejemplo en _demo.tsx_, este código va tener dos valores editables: _name_ y _lastname_ y vamos a tener un control hijo que sólo va a mostrar el _name_ (de hecho este componente sólo pedirá el campo nombre en las propiedades). diff --git a/04-frameworks/01-react/03-react-hooks/08-pure-component/src/index.html b/04-frameworks/01-react/03-react-hooks/08-pure-component/index.html similarity index 54% rename from 04-frameworks/01-react/03-react-hooks/08-pure-component/src/index.html rename to 04-frameworks/01-react/03-react-hooks/08-pure-component/index.html index a3d74b719..892c75140 100644 --- a/04-frameworks/01-react/03-react-hooks/08-pure-component/src/index.html +++ b/04-frameworks/01-react/03-react-hooks/08-pure-component/index.html @@ -1,12 +1,12 @@ - - - - My App Example + + + React App - React hooks
+ diff --git a/04-frameworks/01-react/03-react-hooks/08-pure-component/package.json b/04-frameworks/01-react/03-react-hooks/08-pure-component/package.json index d434b896c..9ee970f00 100644 --- a/04-frameworks/01-react/03-react-hooks/08-pure-component/package.json +++ b/04-frameworks/01-react/03-react-hooks/08-pure-component/package.json @@ -1,40 +1,23 @@ { - "name": "react-example", - "version": "1.0.0", - "description": "", - "main": "index.js", + "name": "hello-vite", + "private": true, + "version": "0.0.0", + "type": "module", "scripts": { - "start": "run-p -l type-check:watch start:dev", - "type-check": "tsc --noEmit", - "type-check:watch": "npm run type-check -- --watch", - "start:dev": "webpack-dev-server --mode development --open", - "build": "rimraf dist && webpack --mode development" + "start": "vite --host", + "build": "vite build", + "preview": "vite preview" }, - "author": "", - "license": "ISC", "devDependencies": { - "@babel/cli": "^7.17.10", - "@babel/core": "^7.17.10", - "@babel/preset-env": "^7.17.10", - "@babel/preset-react": "^7.17.12", - "@babel/preset-typescript": "^7.16.7", - "@types/react": "^18.0.9", - "@types/react-dom": "^18.0.4", - "babel-loader": "^8.2.5", - "css-loader": "^6.7.1", - "html-loader": "^3.1.0", - "html-webpack-plugin": "^5.5.0", - "npm-run-all": "^4.1.5", - "rimraf": "^3.0.2", - "style-loader": "^3.3.1", - "typescript": "^4.6.4", - "webpack": "^5.72.1", - "webpack-cli": "^4.9.2", - "webpack-dev-server": "^4.9.0" + "@types/react": "^19.1.8", + "@types/react-dom": "^19.1.6", + "@vitejs/plugin-react": "^4.6.0", + "typescript": "^5.8.3", + "vite": "^7.0.4", + "vite-plugin-checker": "^0.10.0" }, "dependencies": { - "react": "^18.1.0", - "react-dom": "^18.1.0", - "use-debounce": "^8.0.1" + "react": "^19.1.0", + "react-dom": "^19.1.0" } } diff --git a/04-frameworks/01-react/03-react-hooks/08-pure-component/tsconfig.json b/04-frameworks/01-react/03-react-hooks/08-pure-component/tsconfig.json index 3312b5f1e..a057cea1d 100644 --- a/04-frameworks/01-react/03-react-hooks/08-pure-component/tsconfig.json +++ b/04-frameworks/01-react/03-react-hooks/08-pure-component/tsconfig.json @@ -1,18 +1,19 @@ { "compilerOptions": { - "target": "es6", - "module": "es6", - "moduleResolution": "node", - "declaration": false, + "esModuleInterop": true, + "isolatedModules": true, + "jsx": "react-jsx", + "lib": ["ESNext", "DOM"], + "module": "ESNext", + "moduleResolution": "bundler", + "noEmit": true, "noImplicitAny": false, - "allowSyntheticDefaultImports": true, - "sourceMap": true, - "jsx": "react", - "noLib": false, - "suppressImplicitAnyIndexErrors": true, + "noImplicitReturns": true, + "resolveJsonModule": true, "skipLibCheck": true, - "esModuleInterop": true + "sourceMap": true, + "target": "ESNext", + "useDefineForClassFields": true }, - "include": ["src/**/*"], - "exclude": ["node_modules"] + "include": ["src"] } diff --git a/04-frameworks/01-react/03-react-hooks/08-pure-component/vite.config.ts b/04-frameworks/01-react/03-react-hooks/08-pure-component/vite.config.ts new file mode 100644 index 000000000..a0024d88e --- /dev/null +++ b/04-frameworks/01-react/03-react-hooks/08-pure-component/vite.config.ts @@ -0,0 +1,7 @@ +import { defineConfig } from "vite"; +import checker from "vite-plugin-checker"; +import react from "@vitejs/plugin-react"; + +export default defineConfig({ + plugins: [checker({ typescript: true }), react()], +}); diff --git a/04-frameworks/01-react/03-react-hooks/08-pure-component/webpack.config.js b/04-frameworks/01-react/03-react-hooks/08-pure-component/webpack.config.js deleted file mode 100644 index 326060f82..000000000 --- a/04-frameworks/01-react/03-react-hooks/08-pure-component/webpack.config.js +++ /dev/null @@ -1,54 +0,0 @@ -const HtmlWebpackPlugin = require("html-webpack-plugin"); -const path = require("path"); -const basePath = __dirname; - -module.exports = { - context: path.join(basePath, "src"), - resolve: { - extensions: [".js", ".ts", ".tsx"], - }, - entry: { - app: ["./index.tsx", "./styles.css"], - }, - devtool: "eval-source-map", - stats: "errors-only", - output: { - filename: "[name].[chunkhash].js", - }, - module: { - rules: [ - { - test: /\.tsx?$/, - exclude: /node_modules/, - loader: "babel-loader", - }, - { - test: /\.(png|jpg)$/, - type: "asset/resource", - }, - { - test: /\.html$/, - loader: "html-loader", - }, - { - test: /\.css$/, - exclude: /node_modules/, - use: [ - { - loader: "style-loader", - }, - { - loader: "css-loader", - }, - ], - }, - ], - }, - plugins: [ - //Generate index.html in /dist => https://github.com/ampedandwired/html-webpack-plugin - new HtmlWebpackPlugin({ - filename: "index.html", //Name of file in ./dist/ - template: "index.html", //Name of template in ./src - }), - ], -}; diff --git a/04-frameworks/01-react/03-react-hooks/09-pure-component-callback/.babelrc b/04-frameworks/01-react/03-react-hooks/09-pure-component-callback/.babelrc deleted file mode 100644 index 469d3d55f..000000000 --- a/04-frameworks/01-react/03-react-hooks/09-pure-component-callback/.babelrc +++ /dev/null @@ -1,7 +0,0 @@ -{ - "presets": [ - "@babel/preset-env", - "@babel/preset-typescript", - "@babel/preset-react" - ] -} diff --git a/04-frameworks/01-react/03-react-hooks/09-pure-component-callback/src/index.html b/04-frameworks/01-react/03-react-hooks/09-pure-component-callback/index.html similarity index 54% rename from 04-frameworks/01-react/03-react-hooks/09-pure-component-callback/src/index.html rename to 04-frameworks/01-react/03-react-hooks/09-pure-component-callback/index.html index a3d74b719..892c75140 100644 --- a/04-frameworks/01-react/03-react-hooks/09-pure-component-callback/src/index.html +++ b/04-frameworks/01-react/03-react-hooks/09-pure-component-callback/index.html @@ -1,12 +1,12 @@ - - - - My App Example + + + React App - React hooks
+ diff --git a/04-frameworks/01-react/03-react-hooks/09-pure-component-callback/package.json b/04-frameworks/01-react/03-react-hooks/09-pure-component-callback/package.json index d434b896c..9ee970f00 100644 --- a/04-frameworks/01-react/03-react-hooks/09-pure-component-callback/package.json +++ b/04-frameworks/01-react/03-react-hooks/09-pure-component-callback/package.json @@ -1,40 +1,23 @@ { - "name": "react-example", - "version": "1.0.0", - "description": "", - "main": "index.js", + "name": "hello-vite", + "private": true, + "version": "0.0.0", + "type": "module", "scripts": { - "start": "run-p -l type-check:watch start:dev", - "type-check": "tsc --noEmit", - "type-check:watch": "npm run type-check -- --watch", - "start:dev": "webpack-dev-server --mode development --open", - "build": "rimraf dist && webpack --mode development" + "start": "vite --host", + "build": "vite build", + "preview": "vite preview" }, - "author": "", - "license": "ISC", "devDependencies": { - "@babel/cli": "^7.17.10", - "@babel/core": "^7.17.10", - "@babel/preset-env": "^7.17.10", - "@babel/preset-react": "^7.17.12", - "@babel/preset-typescript": "^7.16.7", - "@types/react": "^18.0.9", - "@types/react-dom": "^18.0.4", - "babel-loader": "^8.2.5", - "css-loader": "^6.7.1", - "html-loader": "^3.1.0", - "html-webpack-plugin": "^5.5.0", - "npm-run-all": "^4.1.5", - "rimraf": "^3.0.2", - "style-loader": "^3.3.1", - "typescript": "^4.6.4", - "webpack": "^5.72.1", - "webpack-cli": "^4.9.2", - "webpack-dev-server": "^4.9.0" + "@types/react": "^19.1.8", + "@types/react-dom": "^19.1.6", + "@vitejs/plugin-react": "^4.6.0", + "typescript": "^5.8.3", + "vite": "^7.0.4", + "vite-plugin-checker": "^0.10.0" }, "dependencies": { - "react": "^18.1.0", - "react-dom": "^18.1.0", - "use-debounce": "^8.0.1" + "react": "^19.1.0", + "react-dom": "^19.1.0" } } diff --git a/04-frameworks/01-react/03-react-hooks/09-pure-component-callback/tsconfig.json b/04-frameworks/01-react/03-react-hooks/09-pure-component-callback/tsconfig.json index 3312b5f1e..a057cea1d 100644 --- a/04-frameworks/01-react/03-react-hooks/09-pure-component-callback/tsconfig.json +++ b/04-frameworks/01-react/03-react-hooks/09-pure-component-callback/tsconfig.json @@ -1,18 +1,19 @@ { "compilerOptions": { - "target": "es6", - "module": "es6", - "moduleResolution": "node", - "declaration": false, + "esModuleInterop": true, + "isolatedModules": true, + "jsx": "react-jsx", + "lib": ["ESNext", "DOM"], + "module": "ESNext", + "moduleResolution": "bundler", + "noEmit": true, "noImplicitAny": false, - "allowSyntheticDefaultImports": true, - "sourceMap": true, - "jsx": "react", - "noLib": false, - "suppressImplicitAnyIndexErrors": true, + "noImplicitReturns": true, + "resolveJsonModule": true, "skipLibCheck": true, - "esModuleInterop": true + "sourceMap": true, + "target": "ESNext", + "useDefineForClassFields": true }, - "include": ["src/**/*"], - "exclude": ["node_modules"] + "include": ["src"] } diff --git a/04-frameworks/01-react/03-react-hooks/09-pure-component-callback/vite.config.ts b/04-frameworks/01-react/03-react-hooks/09-pure-component-callback/vite.config.ts new file mode 100644 index 000000000..a0024d88e --- /dev/null +++ b/04-frameworks/01-react/03-react-hooks/09-pure-component-callback/vite.config.ts @@ -0,0 +1,7 @@ +import { defineConfig } from "vite"; +import checker from "vite-plugin-checker"; +import react from "@vitejs/plugin-react"; + +export default defineConfig({ + plugins: [checker({ typescript: true }), react()], +}); diff --git a/04-frameworks/01-react/03-react-hooks/09-pure-component-callback/webpack.config.js b/04-frameworks/01-react/03-react-hooks/09-pure-component-callback/webpack.config.js deleted file mode 100644 index 326060f82..000000000 --- a/04-frameworks/01-react/03-react-hooks/09-pure-component-callback/webpack.config.js +++ /dev/null @@ -1,54 +0,0 @@ -const HtmlWebpackPlugin = require("html-webpack-plugin"); -const path = require("path"); -const basePath = __dirname; - -module.exports = { - context: path.join(basePath, "src"), - resolve: { - extensions: [".js", ".ts", ".tsx"], - }, - entry: { - app: ["./index.tsx", "./styles.css"], - }, - devtool: "eval-source-map", - stats: "errors-only", - output: { - filename: "[name].[chunkhash].js", - }, - module: { - rules: [ - { - test: /\.tsx?$/, - exclude: /node_modules/, - loader: "babel-loader", - }, - { - test: /\.(png|jpg)$/, - type: "asset/resource", - }, - { - test: /\.html$/, - loader: "html-loader", - }, - { - test: /\.css$/, - exclude: /node_modules/, - use: [ - { - loader: "style-loader", - }, - { - loader: "css-loader", - }, - ], - }, - ], - }, - plugins: [ - //Generate index.html in /dist => https://github.com/ampedandwired/html-webpack-plugin - new HtmlWebpackPlugin({ - filename: "index.html", //Name of file in ./dist/ - template: "index.html", //Name of template in ./src - }), - ], -}; diff --git a/04-frameworks/01-react/03-react-hooks/10-use-reducer/.babelrc b/04-frameworks/01-react/03-react-hooks/10-use-reducer/.babelrc deleted file mode 100644 index 469d3d55f..000000000 --- a/04-frameworks/01-react/03-react-hooks/10-use-reducer/.babelrc +++ /dev/null @@ -1,7 +0,0 @@ -{ - "presets": [ - "@babel/preset-env", - "@babel/preset-typescript", - "@babel/preset-react" - ] -} diff --git a/04-frameworks/01-react/03-react-hooks/10-use-reducer/Readme.md b/04-frameworks/01-react/03-react-hooks/10-use-reducer/Readme.md index 108fa47e7..bfb699c6d 100644 --- a/04-frameworks/01-react/03-react-hooks/10-use-reducer/Readme.md +++ b/04-frameworks/01-react/03-react-hooks/10-use-reducer/Readme.md @@ -1,6 +1,6 @@ # 10 useReducer -## Resume +## Summary This example takes as a starting point _09-pure-component-callback_. diff --git a/04-frameworks/01-react/03-react-hooks/10-use-reducer/index.html b/04-frameworks/01-react/03-react-hooks/10-use-reducer/index.html new file mode 100644 index 000000000..892c75140 --- /dev/null +++ b/04-frameworks/01-react/03-react-hooks/10-use-reducer/index.html @@ -0,0 +1,12 @@ + + + + + + React App - React hooks + + +
+ + + diff --git a/04-frameworks/01-react/03-react-hooks/10-use-reducer/package.json b/04-frameworks/01-react/03-react-hooks/10-use-reducer/package.json index d434b896c..9ee970f00 100644 --- a/04-frameworks/01-react/03-react-hooks/10-use-reducer/package.json +++ b/04-frameworks/01-react/03-react-hooks/10-use-reducer/package.json @@ -1,40 +1,23 @@ { - "name": "react-example", - "version": "1.0.0", - "description": "", - "main": "index.js", + "name": "hello-vite", + "private": true, + "version": "0.0.0", + "type": "module", "scripts": { - "start": "run-p -l type-check:watch start:dev", - "type-check": "tsc --noEmit", - "type-check:watch": "npm run type-check -- --watch", - "start:dev": "webpack-dev-server --mode development --open", - "build": "rimraf dist && webpack --mode development" + "start": "vite --host", + "build": "vite build", + "preview": "vite preview" }, - "author": "", - "license": "ISC", "devDependencies": { - "@babel/cli": "^7.17.10", - "@babel/core": "^7.17.10", - "@babel/preset-env": "^7.17.10", - "@babel/preset-react": "^7.17.12", - "@babel/preset-typescript": "^7.16.7", - "@types/react": "^18.0.9", - "@types/react-dom": "^18.0.4", - "babel-loader": "^8.2.5", - "css-loader": "^6.7.1", - "html-loader": "^3.1.0", - "html-webpack-plugin": "^5.5.0", - "npm-run-all": "^4.1.5", - "rimraf": "^3.0.2", - "style-loader": "^3.3.1", - "typescript": "^4.6.4", - "webpack": "^5.72.1", - "webpack-cli": "^4.9.2", - "webpack-dev-server": "^4.9.0" + "@types/react": "^19.1.8", + "@types/react-dom": "^19.1.6", + "@vitejs/plugin-react": "^4.6.0", + "typescript": "^5.8.3", + "vite": "^7.0.4", + "vite-plugin-checker": "^0.10.0" }, "dependencies": { - "react": "^18.1.0", - "react-dom": "^18.1.0", - "use-debounce": "^8.0.1" + "react": "^19.1.0", + "react-dom": "^19.1.0" } } diff --git a/04-frameworks/01-react/03-react-hooks/10-use-reducer/src/index.html b/04-frameworks/01-react/03-react-hooks/10-use-reducer/src/index.html deleted file mode 100644 index a3d74b719..000000000 --- a/04-frameworks/01-react/03-react-hooks/10-use-reducer/src/index.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - My App Example - - -
- - diff --git a/04-frameworks/01-react/03-react-hooks/10-use-reducer/tsconfig.json b/04-frameworks/01-react/03-react-hooks/10-use-reducer/tsconfig.json index 3312b5f1e..a057cea1d 100644 --- a/04-frameworks/01-react/03-react-hooks/10-use-reducer/tsconfig.json +++ b/04-frameworks/01-react/03-react-hooks/10-use-reducer/tsconfig.json @@ -1,18 +1,19 @@ { "compilerOptions": { - "target": "es6", - "module": "es6", - "moduleResolution": "node", - "declaration": false, + "esModuleInterop": true, + "isolatedModules": true, + "jsx": "react-jsx", + "lib": ["ESNext", "DOM"], + "module": "ESNext", + "moduleResolution": "bundler", + "noEmit": true, "noImplicitAny": false, - "allowSyntheticDefaultImports": true, - "sourceMap": true, - "jsx": "react", - "noLib": false, - "suppressImplicitAnyIndexErrors": true, + "noImplicitReturns": true, + "resolveJsonModule": true, "skipLibCheck": true, - "esModuleInterop": true + "sourceMap": true, + "target": "ESNext", + "useDefineForClassFields": true }, - "include": ["src/**/*"], - "exclude": ["node_modules"] + "include": ["src"] } diff --git a/04-frameworks/01-react/03-react-hooks/10-use-reducer/vite.config.ts b/04-frameworks/01-react/03-react-hooks/10-use-reducer/vite.config.ts new file mode 100644 index 000000000..a0024d88e --- /dev/null +++ b/04-frameworks/01-react/03-react-hooks/10-use-reducer/vite.config.ts @@ -0,0 +1,7 @@ +import { defineConfig } from "vite"; +import checker from "vite-plugin-checker"; +import react from "@vitejs/plugin-react"; + +export default defineConfig({ + plugins: [checker({ typescript: true }), react()], +}); diff --git a/04-frameworks/01-react/03-react-hooks/10-use-reducer/webpack.config.js b/04-frameworks/01-react/03-react-hooks/10-use-reducer/webpack.config.js deleted file mode 100644 index 326060f82..000000000 --- a/04-frameworks/01-react/03-react-hooks/10-use-reducer/webpack.config.js +++ /dev/null @@ -1,54 +0,0 @@ -const HtmlWebpackPlugin = require("html-webpack-plugin"); -const path = require("path"); -const basePath = __dirname; - -module.exports = { - context: path.join(basePath, "src"), - resolve: { - extensions: [".js", ".ts", ".tsx"], - }, - entry: { - app: ["./index.tsx", "./styles.css"], - }, - devtool: "eval-source-map", - stats: "errors-only", - output: { - filename: "[name].[chunkhash].js", - }, - module: { - rules: [ - { - test: /\.tsx?$/, - exclude: /node_modules/, - loader: "babel-loader", - }, - { - test: /\.(png|jpg)$/, - type: "asset/resource", - }, - { - test: /\.html$/, - loader: "html-loader", - }, - { - test: /\.css$/, - exclude: /node_modules/, - use: [ - { - loader: "style-loader", - }, - { - loader: "css-loader", - }, - ], - }, - ], - }, - plugins: [ - //Generate index.html in /dist => https://github.com/ampedandwired/html-webpack-plugin - new HtmlWebpackPlugin({ - filename: "index.html", //Name of file in ./dist/ - template: "index.html", //Name of template in ./src - }), - ], -}; diff --git a/04-frameworks/01-react/03-react-hooks/11-use-context/.babelrc b/04-frameworks/01-react/03-react-hooks/11-use-context/.babelrc deleted file mode 100644 index 469d3d55f..000000000 --- a/04-frameworks/01-react/03-react-hooks/11-use-context/.babelrc +++ /dev/null @@ -1,7 +0,0 @@ -{ - "presets": [ - "@babel/preset-env", - "@babel/preset-typescript", - "@babel/preset-react" - ] -} diff --git a/04-frameworks/01-react/03-react-hooks/11-use-context/Readme.md b/04-frameworks/01-react/03-react-hooks/11-use-context/Readme.md index d14673dd6..ac484cd7f 100644 --- a/04-frameworks/01-react/03-react-hooks/11-use-context/Readme.md +++ b/04-frameworks/01-react/03-react-hooks/11-use-context/Readme.md @@ -1,6 +1,6 @@ # 11 useContext -## Resume +## Summary This example takes the _10-use-reducer_ example as a starting point. @@ -36,22 +36,22 @@ userGlobalDAta.login = "john"; This approach that we could first try to defend (it is flat ES6, so React account only takes care of the UI...), it brings us several problems: -- What if the value of _userGlobalData.login_ changes and I have multiple parts of the application they are using it? How do I notify you of the change? Would have to play pulling and collecting global events to go repainting. +- What if the value of _userGlobalData.login_ changes and I have multiple parts of the application they are using it? How do I notify you of the change? Would have to play pulling and collecting global events to go repainting. - And now to finish, if I want to use Server Side Rendering (that is, pregenerate the pages on the server to serve HTML, this is good for example for have a good SEO), we would have a big problem ... communicating vessels, all the requests would share the same static variables. React incorporates a very powerful mechanism, it is called ** Context ** - - The ** Context ** allows me to share data between components without going through the props. - The Context lives within a React component, with which it is integrated into the React one-way flow, that is, any change you make to it makes updates to be triggered automatically. - I can place the Context at the level I want in the component tree, that is, I can make that data available at the full application level or for example a window containing several tabs. - And to all this we have to add that React incorporates a hook called -_useContext_ which makes using it very easy. +_use_ which makes using it very easy. + +**In previous versions to react 19, use _usecontext_ to consume contexts** Let's see how this works. @@ -99,13 +99,36 @@ const MyContext = React.createContext({ + const [username, setUsername] = React.useState("John Doe"); + + return ( -+ ++ + {props.children} -+ ++ + ); + }; ``` +In previous versions to react 19, the provider is only available as a method inside the context. From react 19, +this is still possible, but only as legacy. We prefer to use the new approach. + +```jsx +import React from "react"; + +const MyContext = React.createContext({ + username: "", + setUsername: () => {}, +}); + +export const MyContextProvider = (props) => { + const [username, setUsername] = React.useState("John Doe"); + + return ( + // MyContext.Provider is legacy + + {props.children} + + ); +}; +``` + Check out what we have here: - We have a component that provides state to our context. @@ -158,7 +181,7 @@ _./src/demo.tsx_ ```diff export const MyComponent = () => { -+ const myContext = React.useContext(MyContext); ++ const myContext = React.use(MyContext); return ( <> @@ -168,6 +191,7 @@ export const MyComponent = () => { ) } ``` + - If we execute the example we can see it working: ```bash diff --git a/04-frameworks/01-react/03-react-hooks/11-use-context/Readme_es.md b/04-frameworks/01-react/03-react-hooks/11-use-context/Readme_es.md index 41e333dfb..ee01b930c 100644 --- a/04-frameworks/01-react/03-react-hooks/11-use-context/Readme_es.md +++ b/04-frameworks/01-react/03-react-hooks/11-use-context/Readme_es.md @@ -69,7 +69,9 @@ React incorpora un mecanismo muy potente, se llama **Context** o de por ejemplo una ventana que contenga varios tabs. Y a todo esto tenemos que añadirle que React incorpora un hook que se llama -_useContext_ que hace que usarlo sea muy facil. +_use_ que hace que usarlo sea muy fácil. + +**En versiones anteriores a la 19, usar _usecontext_ para consumir contextos** Vamos a ver como funciona esto. @@ -122,13 +124,36 @@ const MyContext = React.createContext({ + const [username, setUsername] = React.useState("John Doe"); + + return ( -+ ++ + {props.children} -+ ++ + ); + }; ``` +En versiones anteriores de react 19, el provider está disponible como método dentro de MyContext. En la versión 19 +sigue siendo posible usarlo, aunque se considera legacy. Nosotros nos quedamos con la nueva versión. + +```jsx +import React from "react"; + +const MyContext = React.createContext({ + username: "", + setUsername: () => {}, +}); + +export const MyContextProvider = (props) => { + const [username, setUsername] = React.useState("John Doe"); + + return ( + // MyContext.Provider is legacy + + {props.children} + + ); +}; +``` + Fijate lo que tenemos aqui: - Tenemos un componente que provee de estado a nuestro contexto. @@ -181,7 +206,7 @@ hay debajo del contextprovider lo pinta tal cual ese componente. ```diff export const MyComponent = () => { -+ const myContext = React.useContext(MyContext); ++ const myContext = React.use(MyContext); return ( <> diff --git a/04-frameworks/01-react/03-react-hooks/11-use-context/index.html b/04-frameworks/01-react/03-react-hooks/11-use-context/index.html new file mode 100644 index 000000000..892c75140 --- /dev/null +++ b/04-frameworks/01-react/03-react-hooks/11-use-context/index.html @@ -0,0 +1,12 @@ + + + + + + React App - React hooks + + +
+ + + diff --git a/04-frameworks/01-react/03-react-hooks/11-use-context/package.json b/04-frameworks/01-react/03-react-hooks/11-use-context/package.json index d434b896c..9ee970f00 100644 --- a/04-frameworks/01-react/03-react-hooks/11-use-context/package.json +++ b/04-frameworks/01-react/03-react-hooks/11-use-context/package.json @@ -1,40 +1,23 @@ { - "name": "react-example", - "version": "1.0.0", - "description": "", - "main": "index.js", + "name": "hello-vite", + "private": true, + "version": "0.0.0", + "type": "module", "scripts": { - "start": "run-p -l type-check:watch start:dev", - "type-check": "tsc --noEmit", - "type-check:watch": "npm run type-check -- --watch", - "start:dev": "webpack-dev-server --mode development --open", - "build": "rimraf dist && webpack --mode development" + "start": "vite --host", + "build": "vite build", + "preview": "vite preview" }, - "author": "", - "license": "ISC", "devDependencies": { - "@babel/cli": "^7.17.10", - "@babel/core": "^7.17.10", - "@babel/preset-env": "^7.17.10", - "@babel/preset-react": "^7.17.12", - "@babel/preset-typescript": "^7.16.7", - "@types/react": "^18.0.9", - "@types/react-dom": "^18.0.4", - "babel-loader": "^8.2.5", - "css-loader": "^6.7.1", - "html-loader": "^3.1.0", - "html-webpack-plugin": "^5.5.0", - "npm-run-all": "^4.1.5", - "rimraf": "^3.0.2", - "style-loader": "^3.3.1", - "typescript": "^4.6.4", - "webpack": "^5.72.1", - "webpack-cli": "^4.9.2", - "webpack-dev-server": "^4.9.0" + "@types/react": "^19.1.8", + "@types/react-dom": "^19.1.6", + "@vitejs/plugin-react": "^4.6.0", + "typescript": "^5.8.3", + "vite": "^7.0.4", + "vite-plugin-checker": "^0.10.0" }, "dependencies": { - "react": "^18.1.0", - "react-dom": "^18.1.0", - "use-debounce": "^8.0.1" + "react": "^19.1.0", + "react-dom": "^19.1.0" } } diff --git a/04-frameworks/01-react/03-react-hooks/11-use-context/src/demo.tsx b/04-frameworks/01-react/03-react-hooks/11-use-context/src/demo.tsx index 64134de6c..766e3c846 100644 --- a/04-frameworks/01-react/03-react-hooks/11-use-context/src/demo.tsx +++ b/04-frameworks/01-react/03-react-hooks/11-use-context/src/demo.tsx @@ -14,9 +14,7 @@ export const MyContextProvider = (props) => { const [username, setUsername] = React.useState("John Doe"); return ( - - {props.children} - + {props.children} ); }; diff --git a/04-frameworks/01-react/03-react-hooks/11-use-context/src/index.html b/04-frameworks/01-react/03-react-hooks/11-use-context/src/index.html deleted file mode 100644 index a3d74b719..000000000 --- a/04-frameworks/01-react/03-react-hooks/11-use-context/src/index.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - My App Example - - -
- - diff --git a/04-frameworks/01-react/03-react-hooks/11-use-context/tsconfig.json b/04-frameworks/01-react/03-react-hooks/11-use-context/tsconfig.json index 3312b5f1e..a057cea1d 100644 --- a/04-frameworks/01-react/03-react-hooks/11-use-context/tsconfig.json +++ b/04-frameworks/01-react/03-react-hooks/11-use-context/tsconfig.json @@ -1,18 +1,19 @@ { "compilerOptions": { - "target": "es6", - "module": "es6", - "moduleResolution": "node", - "declaration": false, + "esModuleInterop": true, + "isolatedModules": true, + "jsx": "react-jsx", + "lib": ["ESNext", "DOM"], + "module": "ESNext", + "moduleResolution": "bundler", + "noEmit": true, "noImplicitAny": false, - "allowSyntheticDefaultImports": true, - "sourceMap": true, - "jsx": "react", - "noLib": false, - "suppressImplicitAnyIndexErrors": true, + "noImplicitReturns": true, + "resolveJsonModule": true, "skipLibCheck": true, - "esModuleInterop": true + "sourceMap": true, + "target": "ESNext", + "useDefineForClassFields": true }, - "include": ["src/**/*"], - "exclude": ["node_modules"] + "include": ["src"] } diff --git a/04-frameworks/01-react/03-react-hooks/11-use-context/vite.config.ts b/04-frameworks/01-react/03-react-hooks/11-use-context/vite.config.ts new file mode 100644 index 000000000..a0024d88e --- /dev/null +++ b/04-frameworks/01-react/03-react-hooks/11-use-context/vite.config.ts @@ -0,0 +1,7 @@ +import { defineConfig } from "vite"; +import checker from "vite-plugin-checker"; +import react from "@vitejs/plugin-react"; + +export default defineConfig({ + plugins: [checker({ typescript: true }), react()], +}); diff --git a/04-frameworks/01-react/03-react-hooks/11-use-context/webpack.config.js b/04-frameworks/01-react/03-react-hooks/11-use-context/webpack.config.js deleted file mode 100644 index 326060f82..000000000 --- a/04-frameworks/01-react/03-react-hooks/11-use-context/webpack.config.js +++ /dev/null @@ -1,54 +0,0 @@ -const HtmlWebpackPlugin = require("html-webpack-plugin"); -const path = require("path"); -const basePath = __dirname; - -module.exports = { - context: path.join(basePath, "src"), - resolve: { - extensions: [".js", ".ts", ".tsx"], - }, - entry: { - app: ["./index.tsx", "./styles.css"], - }, - devtool: "eval-source-map", - stats: "errors-only", - output: { - filename: "[name].[chunkhash].js", - }, - module: { - rules: [ - { - test: /\.tsx?$/, - exclude: /node_modules/, - loader: "babel-loader", - }, - { - test: /\.(png|jpg)$/, - type: "asset/resource", - }, - { - test: /\.html$/, - loader: "html-loader", - }, - { - test: /\.css$/, - exclude: /node_modules/, - use: [ - { - loader: "style-loader", - }, - { - loader: "css-loader", - }, - ], - }, - ], - }, - plugins: [ - //Generate index.html in /dist => https://github.com/ampedandwired/html-webpack-plugin - new HtmlWebpackPlugin({ - filename: "index.html", //Name of file in ./dist/ - template: "index.html", //Name of template in ./src - }), - ], -}; diff --git a/04-frameworks/01-react/03-react-hooks/12-set-state-func/.babelrc b/04-frameworks/01-react/03-react-hooks/12-set-state-func/.babelrc deleted file mode 100644 index 469d3d55f..000000000 --- a/04-frameworks/01-react/03-react-hooks/12-set-state-func/.babelrc +++ /dev/null @@ -1,7 +0,0 @@ -{ - "presets": [ - "@babel/preset-env", - "@babel/preset-typescript", - "@babel/preset-react" - ] -} diff --git a/04-frameworks/01-react/03-react-hooks/12-set-state-func/Readme.md b/04-frameworks/01-react/03-react-hooks/12-set-state-func/Readme.md index 7c723e258..0f1b944be 100644 --- a/04-frameworks/01-react/03-react-hooks/12-set-state-func/Readme.md +++ b/04-frameworks/01-react/03-react-hooks/12-set-state-func/Readme.md @@ -1,6 +1,6 @@ # 12 set state func -## Resume +## Summary This example takes the _11-use-context_ example as a starting point. diff --git a/04-frameworks/01-react/03-react-hooks/12-set-state-func/index.html b/04-frameworks/01-react/03-react-hooks/12-set-state-func/index.html new file mode 100644 index 000000000..892c75140 --- /dev/null +++ b/04-frameworks/01-react/03-react-hooks/12-set-state-func/index.html @@ -0,0 +1,12 @@ + + + + + + React App - React hooks + + +
+ + + diff --git a/04-frameworks/01-react/03-react-hooks/12-set-state-func/package.json b/04-frameworks/01-react/03-react-hooks/12-set-state-func/package.json index d434b896c..9ee970f00 100644 --- a/04-frameworks/01-react/03-react-hooks/12-set-state-func/package.json +++ b/04-frameworks/01-react/03-react-hooks/12-set-state-func/package.json @@ -1,40 +1,23 @@ { - "name": "react-example", - "version": "1.0.0", - "description": "", - "main": "index.js", + "name": "hello-vite", + "private": true, + "version": "0.0.0", + "type": "module", "scripts": { - "start": "run-p -l type-check:watch start:dev", - "type-check": "tsc --noEmit", - "type-check:watch": "npm run type-check -- --watch", - "start:dev": "webpack-dev-server --mode development --open", - "build": "rimraf dist && webpack --mode development" + "start": "vite --host", + "build": "vite build", + "preview": "vite preview" }, - "author": "", - "license": "ISC", "devDependencies": { - "@babel/cli": "^7.17.10", - "@babel/core": "^7.17.10", - "@babel/preset-env": "^7.17.10", - "@babel/preset-react": "^7.17.12", - "@babel/preset-typescript": "^7.16.7", - "@types/react": "^18.0.9", - "@types/react-dom": "^18.0.4", - "babel-loader": "^8.2.5", - "css-loader": "^6.7.1", - "html-loader": "^3.1.0", - "html-webpack-plugin": "^5.5.0", - "npm-run-all": "^4.1.5", - "rimraf": "^3.0.2", - "style-loader": "^3.3.1", - "typescript": "^4.6.4", - "webpack": "^5.72.1", - "webpack-cli": "^4.9.2", - "webpack-dev-server": "^4.9.0" + "@types/react": "^19.1.8", + "@types/react-dom": "^19.1.6", + "@vitejs/plugin-react": "^4.6.0", + "typescript": "^5.8.3", + "vite": "^7.0.4", + "vite-plugin-checker": "^0.10.0" }, "dependencies": { - "react": "^18.1.0", - "react-dom": "^18.1.0", - "use-debounce": "^8.0.1" + "react": "^19.1.0", + "react-dom": "^19.1.0" } } diff --git a/04-frameworks/01-react/03-react-hooks/12-set-state-func/src/index.html b/04-frameworks/01-react/03-react-hooks/12-set-state-func/src/index.html deleted file mode 100644 index a3d74b719..000000000 --- a/04-frameworks/01-react/03-react-hooks/12-set-state-func/src/index.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - My App Example - - -
- - diff --git a/04-frameworks/01-react/03-react-hooks/12-set-state-func/tsconfig.json b/04-frameworks/01-react/03-react-hooks/12-set-state-func/tsconfig.json index 3312b5f1e..a057cea1d 100644 --- a/04-frameworks/01-react/03-react-hooks/12-set-state-func/tsconfig.json +++ b/04-frameworks/01-react/03-react-hooks/12-set-state-func/tsconfig.json @@ -1,18 +1,19 @@ { "compilerOptions": { - "target": "es6", - "module": "es6", - "moduleResolution": "node", - "declaration": false, + "esModuleInterop": true, + "isolatedModules": true, + "jsx": "react-jsx", + "lib": ["ESNext", "DOM"], + "module": "ESNext", + "moduleResolution": "bundler", + "noEmit": true, "noImplicitAny": false, - "allowSyntheticDefaultImports": true, - "sourceMap": true, - "jsx": "react", - "noLib": false, - "suppressImplicitAnyIndexErrors": true, + "noImplicitReturns": true, + "resolveJsonModule": true, "skipLibCheck": true, - "esModuleInterop": true + "sourceMap": true, + "target": "ESNext", + "useDefineForClassFields": true }, - "include": ["src/**/*"], - "exclude": ["node_modules"] + "include": ["src"] } diff --git a/04-frameworks/01-react/03-react-hooks/12-set-state-func/vite.config.ts b/04-frameworks/01-react/03-react-hooks/12-set-state-func/vite.config.ts new file mode 100644 index 000000000..a0024d88e --- /dev/null +++ b/04-frameworks/01-react/03-react-hooks/12-set-state-func/vite.config.ts @@ -0,0 +1,7 @@ +import { defineConfig } from "vite"; +import checker from "vite-plugin-checker"; +import react from "@vitejs/plugin-react"; + +export default defineConfig({ + plugins: [checker({ typescript: true }), react()], +}); diff --git a/04-frameworks/01-react/03-react-hooks/12-set-state-func/webpack.config.js b/04-frameworks/01-react/03-react-hooks/12-set-state-func/webpack.config.js deleted file mode 100644 index 326060f82..000000000 --- a/04-frameworks/01-react/03-react-hooks/12-set-state-func/webpack.config.js +++ /dev/null @@ -1,54 +0,0 @@ -const HtmlWebpackPlugin = require("html-webpack-plugin"); -const path = require("path"); -const basePath = __dirname; - -module.exports = { - context: path.join(basePath, "src"), - resolve: { - extensions: [".js", ".ts", ".tsx"], - }, - entry: { - app: ["./index.tsx", "./styles.css"], - }, - devtool: "eval-source-map", - stats: "errors-only", - output: { - filename: "[name].[chunkhash].js", - }, - module: { - rules: [ - { - test: /\.tsx?$/, - exclude: /node_modules/, - loader: "babel-loader", - }, - { - test: /\.(png|jpg)$/, - type: "asset/resource", - }, - { - test: /\.html$/, - loader: "html-loader", - }, - { - test: /\.css$/, - exclude: /node_modules/, - use: [ - { - loader: "style-loader", - }, - { - loader: "css-loader", - }, - ], - }, - ], - }, - plugins: [ - //Generate index.html in /dist => https://github.com/ampedandwired/html-webpack-plugin - new HtmlWebpackPlugin({ - filename: "index.html", //Name of file in ./dist/ - template: "index.html", //Name of template in ./src - }), - ], -}; diff --git a/04-frameworks/01-react/03-react-hooks/13-async-closure/.babelrc b/04-frameworks/01-react/03-react-hooks/13-async-closure/.babelrc deleted file mode 100644 index 469d3d55f..000000000 --- a/04-frameworks/01-react/03-react-hooks/13-async-closure/.babelrc +++ /dev/null @@ -1,7 +0,0 @@ -{ - "presets": [ - "@babel/preset-env", - "@babel/preset-typescript", - "@babel/preset-react" - ] -} diff --git a/04-frameworks/01-react/03-react-hooks/13-async-closure/index.html b/04-frameworks/01-react/03-react-hooks/13-async-closure/index.html new file mode 100644 index 000000000..892c75140 --- /dev/null +++ b/04-frameworks/01-react/03-react-hooks/13-async-closure/index.html @@ -0,0 +1,12 @@ + + + + + + React App - React hooks + + +
+ + + diff --git a/04-frameworks/01-react/03-react-hooks/13-async-closure/package.json b/04-frameworks/01-react/03-react-hooks/13-async-closure/package.json index d434b896c..9ee970f00 100644 --- a/04-frameworks/01-react/03-react-hooks/13-async-closure/package.json +++ b/04-frameworks/01-react/03-react-hooks/13-async-closure/package.json @@ -1,40 +1,23 @@ { - "name": "react-example", - "version": "1.0.0", - "description": "", - "main": "index.js", + "name": "hello-vite", + "private": true, + "version": "0.0.0", + "type": "module", "scripts": { - "start": "run-p -l type-check:watch start:dev", - "type-check": "tsc --noEmit", - "type-check:watch": "npm run type-check -- --watch", - "start:dev": "webpack-dev-server --mode development --open", - "build": "rimraf dist && webpack --mode development" + "start": "vite --host", + "build": "vite build", + "preview": "vite preview" }, - "author": "", - "license": "ISC", "devDependencies": { - "@babel/cli": "^7.17.10", - "@babel/core": "^7.17.10", - "@babel/preset-env": "^7.17.10", - "@babel/preset-react": "^7.17.12", - "@babel/preset-typescript": "^7.16.7", - "@types/react": "^18.0.9", - "@types/react-dom": "^18.0.4", - "babel-loader": "^8.2.5", - "css-loader": "^6.7.1", - "html-loader": "^3.1.0", - "html-webpack-plugin": "^5.5.0", - "npm-run-all": "^4.1.5", - "rimraf": "^3.0.2", - "style-loader": "^3.3.1", - "typescript": "^4.6.4", - "webpack": "^5.72.1", - "webpack-cli": "^4.9.2", - "webpack-dev-server": "^4.9.0" + "@types/react": "^19.1.8", + "@types/react-dom": "^19.1.6", + "@vitejs/plugin-react": "^4.6.0", + "typescript": "^5.8.3", + "vite": "^7.0.4", + "vite-plugin-checker": "^0.10.0" }, "dependencies": { - "react": "^18.1.0", - "react-dom": "^18.1.0", - "use-debounce": "^8.0.1" + "react": "^19.1.0", + "react-dom": "^19.1.0" } } diff --git a/04-frameworks/01-react/03-react-hooks/13-async-closure/src/index.html b/04-frameworks/01-react/03-react-hooks/13-async-closure/src/index.html deleted file mode 100644 index a3d74b719..000000000 --- a/04-frameworks/01-react/03-react-hooks/13-async-closure/src/index.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - My App Example - - -
- - diff --git a/04-frameworks/01-react/03-react-hooks/13-async-closure/tsconfig.json b/04-frameworks/01-react/03-react-hooks/13-async-closure/tsconfig.json index 3312b5f1e..a057cea1d 100644 --- a/04-frameworks/01-react/03-react-hooks/13-async-closure/tsconfig.json +++ b/04-frameworks/01-react/03-react-hooks/13-async-closure/tsconfig.json @@ -1,18 +1,19 @@ { "compilerOptions": { - "target": "es6", - "module": "es6", - "moduleResolution": "node", - "declaration": false, + "esModuleInterop": true, + "isolatedModules": true, + "jsx": "react-jsx", + "lib": ["ESNext", "DOM"], + "module": "ESNext", + "moduleResolution": "bundler", + "noEmit": true, "noImplicitAny": false, - "allowSyntheticDefaultImports": true, - "sourceMap": true, - "jsx": "react", - "noLib": false, - "suppressImplicitAnyIndexErrors": true, + "noImplicitReturns": true, + "resolveJsonModule": true, "skipLibCheck": true, - "esModuleInterop": true + "sourceMap": true, + "target": "ESNext", + "useDefineForClassFields": true }, - "include": ["src/**/*"], - "exclude": ["node_modules"] + "include": ["src"] } diff --git a/04-frameworks/01-react/03-react-hooks/13-async-closure/vite.config.ts b/04-frameworks/01-react/03-react-hooks/13-async-closure/vite.config.ts new file mode 100644 index 000000000..a0024d88e --- /dev/null +++ b/04-frameworks/01-react/03-react-hooks/13-async-closure/vite.config.ts @@ -0,0 +1,7 @@ +import { defineConfig } from "vite"; +import checker from "vite-plugin-checker"; +import react from "@vitejs/plugin-react"; + +export default defineConfig({ + plugins: [checker({ typescript: true }), react()], +}); diff --git a/04-frameworks/01-react/03-react-hooks/13-async-closure/webpack.config.js b/04-frameworks/01-react/03-react-hooks/13-async-closure/webpack.config.js deleted file mode 100644 index 326060f82..000000000 --- a/04-frameworks/01-react/03-react-hooks/13-async-closure/webpack.config.js +++ /dev/null @@ -1,54 +0,0 @@ -const HtmlWebpackPlugin = require("html-webpack-plugin"); -const path = require("path"); -const basePath = __dirname; - -module.exports = { - context: path.join(basePath, "src"), - resolve: { - extensions: [".js", ".ts", ".tsx"], - }, - entry: { - app: ["./index.tsx", "./styles.css"], - }, - devtool: "eval-source-map", - stats: "errors-only", - output: { - filename: "[name].[chunkhash].js", - }, - module: { - rules: [ - { - test: /\.tsx?$/, - exclude: /node_modules/, - loader: "babel-loader", - }, - { - test: /\.(png|jpg)$/, - type: "asset/resource", - }, - { - test: /\.html$/, - loader: "html-loader", - }, - { - test: /\.css$/, - exclude: /node_modules/, - use: [ - { - loader: "style-loader", - }, - { - loader: "css-loader", - }, - ], - }, - ], - }, - plugins: [ - //Generate index.html in /dist => https://github.com/ampedandwired/html-webpack-plugin - new HtmlWebpackPlugin({ - filename: "index.html", //Name of file in ./dist/ - template: "index.html", //Name of template in ./src - }), - ], -}; diff --git a/04-frameworks/01-react/03-react-hooks/14-use-ref-dom/.babelrc b/04-frameworks/01-react/03-react-hooks/14-use-ref-dom/.babelrc deleted file mode 100644 index 469d3d55f..000000000 --- a/04-frameworks/01-react/03-react-hooks/14-use-ref-dom/.babelrc +++ /dev/null @@ -1,7 +0,0 @@ -{ - "presets": [ - "@babel/preset-env", - "@babel/preset-typescript", - "@babel/preset-react" - ] -} diff --git a/04-frameworks/01-react/03-react-hooks/14-use-ref-dom/Readme_es.md b/04-frameworks/01-react/03-react-hooks/14-use-ref-dom/Readme_es.md index c59aeaf25..c5164ace8 100644 --- a/04-frameworks/01-react/03-react-hooks/14-use-ref-dom/Readme_es.md +++ b/04-frameworks/01-react/03-react-hooks/14-use-ref-dom/Readme_es.md @@ -12,7 +12,7 @@ vamos a usarlo para acceder a un nodo del dom. npm install ``` -- En _demo.js_ pegamos el siguiente código (fijate que aquí definimos +- En _demo.tsx_ pegamos el siguiente código (fijate que aquí definimos el _useRef_ y lo asociamos en el _div_ container). _./src/demo.tsx_ diff --git a/04-frameworks/01-react/03-react-hooks/14-use-ref-dom/index.html b/04-frameworks/01-react/03-react-hooks/14-use-ref-dom/index.html new file mode 100644 index 000000000..892c75140 --- /dev/null +++ b/04-frameworks/01-react/03-react-hooks/14-use-ref-dom/index.html @@ -0,0 +1,12 @@ + + + + + + React App - React hooks + + +
+ + + diff --git a/04-frameworks/01-react/03-react-hooks/14-use-ref-dom/package.json b/04-frameworks/01-react/03-react-hooks/14-use-ref-dom/package.json index d434b896c..9ee970f00 100644 --- a/04-frameworks/01-react/03-react-hooks/14-use-ref-dom/package.json +++ b/04-frameworks/01-react/03-react-hooks/14-use-ref-dom/package.json @@ -1,40 +1,23 @@ { - "name": "react-example", - "version": "1.0.0", - "description": "", - "main": "index.js", + "name": "hello-vite", + "private": true, + "version": "0.0.0", + "type": "module", "scripts": { - "start": "run-p -l type-check:watch start:dev", - "type-check": "tsc --noEmit", - "type-check:watch": "npm run type-check -- --watch", - "start:dev": "webpack-dev-server --mode development --open", - "build": "rimraf dist && webpack --mode development" + "start": "vite --host", + "build": "vite build", + "preview": "vite preview" }, - "author": "", - "license": "ISC", "devDependencies": { - "@babel/cli": "^7.17.10", - "@babel/core": "^7.17.10", - "@babel/preset-env": "^7.17.10", - "@babel/preset-react": "^7.17.12", - "@babel/preset-typescript": "^7.16.7", - "@types/react": "^18.0.9", - "@types/react-dom": "^18.0.4", - "babel-loader": "^8.2.5", - "css-loader": "^6.7.1", - "html-loader": "^3.1.0", - "html-webpack-plugin": "^5.5.0", - "npm-run-all": "^4.1.5", - "rimraf": "^3.0.2", - "style-loader": "^3.3.1", - "typescript": "^4.6.4", - "webpack": "^5.72.1", - "webpack-cli": "^4.9.2", - "webpack-dev-server": "^4.9.0" + "@types/react": "^19.1.8", + "@types/react-dom": "^19.1.6", + "@vitejs/plugin-react": "^4.6.0", + "typescript": "^5.8.3", + "vite": "^7.0.4", + "vite-plugin-checker": "^0.10.0" }, "dependencies": { - "react": "^18.1.0", - "react-dom": "^18.1.0", - "use-debounce": "^8.0.1" + "react": "^19.1.0", + "react-dom": "^19.1.0" } } diff --git a/04-frameworks/01-react/03-react-hooks/14-use-ref-dom/src/index.html b/04-frameworks/01-react/03-react-hooks/14-use-ref-dom/src/index.html deleted file mode 100644 index a3d74b719..000000000 --- a/04-frameworks/01-react/03-react-hooks/14-use-ref-dom/src/index.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - My App Example - - -
- - diff --git a/04-frameworks/01-react/03-react-hooks/14-use-ref-dom/tsconfig.json b/04-frameworks/01-react/03-react-hooks/14-use-ref-dom/tsconfig.json index 3312b5f1e..a057cea1d 100644 --- a/04-frameworks/01-react/03-react-hooks/14-use-ref-dom/tsconfig.json +++ b/04-frameworks/01-react/03-react-hooks/14-use-ref-dom/tsconfig.json @@ -1,18 +1,19 @@ { "compilerOptions": { - "target": "es6", - "module": "es6", - "moduleResolution": "node", - "declaration": false, + "esModuleInterop": true, + "isolatedModules": true, + "jsx": "react-jsx", + "lib": ["ESNext", "DOM"], + "module": "ESNext", + "moduleResolution": "bundler", + "noEmit": true, "noImplicitAny": false, - "allowSyntheticDefaultImports": true, - "sourceMap": true, - "jsx": "react", - "noLib": false, - "suppressImplicitAnyIndexErrors": true, + "noImplicitReturns": true, + "resolveJsonModule": true, "skipLibCheck": true, - "esModuleInterop": true + "sourceMap": true, + "target": "ESNext", + "useDefineForClassFields": true }, - "include": ["src/**/*"], - "exclude": ["node_modules"] + "include": ["src"] } diff --git a/04-frameworks/01-react/03-react-hooks/14-use-ref-dom/vite.config.ts b/04-frameworks/01-react/03-react-hooks/14-use-ref-dom/vite.config.ts new file mode 100644 index 000000000..a0024d88e --- /dev/null +++ b/04-frameworks/01-react/03-react-hooks/14-use-ref-dom/vite.config.ts @@ -0,0 +1,7 @@ +import { defineConfig } from "vite"; +import checker from "vite-plugin-checker"; +import react from "@vitejs/plugin-react"; + +export default defineConfig({ + plugins: [checker({ typescript: true }), react()], +}); diff --git a/04-frameworks/01-react/03-react-hooks/14-use-ref-dom/webpack.config.js b/04-frameworks/01-react/03-react-hooks/14-use-ref-dom/webpack.config.js deleted file mode 100644 index 326060f82..000000000 --- a/04-frameworks/01-react/03-react-hooks/14-use-ref-dom/webpack.config.js +++ /dev/null @@ -1,54 +0,0 @@ -const HtmlWebpackPlugin = require("html-webpack-plugin"); -const path = require("path"); -const basePath = __dirname; - -module.exports = { - context: path.join(basePath, "src"), - resolve: { - extensions: [".js", ".ts", ".tsx"], - }, - entry: { - app: ["./index.tsx", "./styles.css"], - }, - devtool: "eval-source-map", - stats: "errors-only", - output: { - filename: "[name].[chunkhash].js", - }, - module: { - rules: [ - { - test: /\.tsx?$/, - exclude: /node_modules/, - loader: "babel-loader", - }, - { - test: /\.(png|jpg)$/, - type: "asset/resource", - }, - { - test: /\.html$/, - loader: "html-loader", - }, - { - test: /\.css$/, - exclude: /node_modules/, - use: [ - { - loader: "style-loader", - }, - { - loader: "css-loader", - }, - ], - }, - ], - }, - plugins: [ - //Generate index.html in /dist => https://github.com/ampedandwired/html-webpack-plugin - new HtmlWebpackPlugin({ - filename: "index.html", //Name of file in ./dist/ - template: "index.html", //Name of template in ./src - }), - ], -}; diff --git a/04-frameworks/01-react/03-react-hooks/15-memo-predicate/.babelrc b/04-frameworks/01-react/03-react-hooks/15-memo-predicate/.babelrc deleted file mode 100644 index 469d3d55f..000000000 --- a/04-frameworks/01-react/03-react-hooks/15-memo-predicate/.babelrc +++ /dev/null @@ -1,7 +0,0 @@ -{ - "presets": [ - "@babel/preset-env", - "@babel/preset-typescript", - "@babel/preset-react" - ] -} diff --git a/04-frameworks/01-react/03-react-hooks/15-memo-predicate/Readme.md b/04-frameworks/01-react/03-react-hooks/15-memo-predicate/Readme.md index ba8d8c3e4..e96333d34 100644 --- a/04-frameworks/01-react/03-react-hooks/15-memo-predicate/Readme.md +++ b/04-frameworks/01-react/03-react-hooks/15-memo-predicate/Readme.md @@ -12,19 +12,6 @@ We are going to implement a customer satisfaction widget, based on smily faces, npm install ``` -- We have to make a slight change in this example in our _webpack.config.js_ - -```diff -... - { - test: /\.(png|jpg)$/, - exclude: /node_modules/, -- loader: "url-loader", -+ type: "asset/resource", - }, -... -``` - - Let's copy the five smiley faces (you can copy them from the sample implementation in github) into the route _src/assets_. - Let's add the following content into the _src/styles.css_ css file to add the smileys styles: diff --git a/04-frameworks/01-react/03-react-hooks/15-memo-predicate/index.html b/04-frameworks/01-react/03-react-hooks/15-memo-predicate/index.html new file mode 100644 index 000000000..892c75140 --- /dev/null +++ b/04-frameworks/01-react/03-react-hooks/15-memo-predicate/index.html @@ -0,0 +1,12 @@ + + + + + + React App - React hooks + + +
+ + + diff --git a/04-frameworks/01-react/03-react-hooks/15-memo-predicate/package.json b/04-frameworks/01-react/03-react-hooks/15-memo-predicate/package.json index d434b896c..9ee970f00 100644 --- a/04-frameworks/01-react/03-react-hooks/15-memo-predicate/package.json +++ b/04-frameworks/01-react/03-react-hooks/15-memo-predicate/package.json @@ -1,40 +1,23 @@ { - "name": "react-example", - "version": "1.0.0", - "description": "", - "main": "index.js", + "name": "hello-vite", + "private": true, + "version": "0.0.0", + "type": "module", "scripts": { - "start": "run-p -l type-check:watch start:dev", - "type-check": "tsc --noEmit", - "type-check:watch": "npm run type-check -- --watch", - "start:dev": "webpack-dev-server --mode development --open", - "build": "rimraf dist && webpack --mode development" + "start": "vite --host", + "build": "vite build", + "preview": "vite preview" }, - "author": "", - "license": "ISC", "devDependencies": { - "@babel/cli": "^7.17.10", - "@babel/core": "^7.17.10", - "@babel/preset-env": "^7.17.10", - "@babel/preset-react": "^7.17.12", - "@babel/preset-typescript": "^7.16.7", - "@types/react": "^18.0.9", - "@types/react-dom": "^18.0.4", - "babel-loader": "^8.2.5", - "css-loader": "^6.7.1", - "html-loader": "^3.1.0", - "html-webpack-plugin": "^5.5.0", - "npm-run-all": "^4.1.5", - "rimraf": "^3.0.2", - "style-loader": "^3.3.1", - "typescript": "^4.6.4", - "webpack": "^5.72.1", - "webpack-cli": "^4.9.2", - "webpack-dev-server": "^4.9.0" + "@types/react": "^19.1.8", + "@types/react-dom": "^19.1.6", + "@vitejs/plugin-react": "^4.6.0", + "typescript": "^5.8.3", + "vite": "^7.0.4", + "vite-plugin-checker": "^0.10.0" }, "dependencies": { - "react": "^18.1.0", - "react-dom": "^18.1.0", - "use-debounce": "^8.0.1" + "react": "^19.1.0", + "react-dom": "^19.1.0" } } diff --git a/04-frameworks/01-react/03-react-hooks/15-memo-predicate/src/index.html b/04-frameworks/01-react/03-react-hooks/15-memo-predicate/src/index.html deleted file mode 100644 index a3d74b719..000000000 --- a/04-frameworks/01-react/03-react-hooks/15-memo-predicate/src/index.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - My App Example - - -
- - diff --git a/04-frameworks/01-react/03-react-hooks/15-memo-predicate/src/index.tsx b/04-frameworks/01-react/03-react-hooks/15-memo-predicate/src/index.tsx index 7e439b87e..7c541901b 100644 --- a/04-frameworks/01-react/03-react-hooks/15-memo-predicate/src/index.tsx +++ b/04-frameworks/01-react/03-react-hooks/15-memo-predicate/src/index.tsx @@ -1,6 +1,7 @@ import React from "react"; import { createRoot } from "react-dom/client"; import { App } from "./app"; +import "./styles.css"; const container = document.getElementById("root"); const root = createRoot(container); diff --git a/04-frameworks/01-react/03-react-hooks/15-memo-predicate/tsconfig.json b/04-frameworks/01-react/03-react-hooks/15-memo-predicate/tsconfig.json index 3312b5f1e..a057cea1d 100644 --- a/04-frameworks/01-react/03-react-hooks/15-memo-predicate/tsconfig.json +++ b/04-frameworks/01-react/03-react-hooks/15-memo-predicate/tsconfig.json @@ -1,18 +1,19 @@ { "compilerOptions": { - "target": "es6", - "module": "es6", - "moduleResolution": "node", - "declaration": false, + "esModuleInterop": true, + "isolatedModules": true, + "jsx": "react-jsx", + "lib": ["ESNext", "DOM"], + "module": "ESNext", + "moduleResolution": "bundler", + "noEmit": true, "noImplicitAny": false, - "allowSyntheticDefaultImports": true, - "sourceMap": true, - "jsx": "react", - "noLib": false, - "suppressImplicitAnyIndexErrors": true, + "noImplicitReturns": true, + "resolveJsonModule": true, "skipLibCheck": true, - "esModuleInterop": true + "sourceMap": true, + "target": "ESNext", + "useDefineForClassFields": true }, - "include": ["src/**/*"], - "exclude": ["node_modules"] + "include": ["src"] } diff --git a/04-frameworks/01-react/03-react-hooks/15-memo-predicate/vite.config.ts b/04-frameworks/01-react/03-react-hooks/15-memo-predicate/vite.config.ts new file mode 100644 index 000000000..a0024d88e --- /dev/null +++ b/04-frameworks/01-react/03-react-hooks/15-memo-predicate/vite.config.ts @@ -0,0 +1,7 @@ +import { defineConfig } from "vite"; +import checker from "vite-plugin-checker"; +import react from "@vitejs/plugin-react"; + +export default defineConfig({ + plugins: [checker({ typescript: true }), react()], +}); diff --git a/04-frameworks/01-react/03-react-hooks/15-memo-predicate/webpack.config.js b/04-frameworks/01-react/03-react-hooks/15-memo-predicate/webpack.config.js deleted file mode 100644 index 326060f82..000000000 --- a/04-frameworks/01-react/03-react-hooks/15-memo-predicate/webpack.config.js +++ /dev/null @@ -1,54 +0,0 @@ -const HtmlWebpackPlugin = require("html-webpack-plugin"); -const path = require("path"); -const basePath = __dirname; - -module.exports = { - context: path.join(basePath, "src"), - resolve: { - extensions: [".js", ".ts", ".tsx"], - }, - entry: { - app: ["./index.tsx", "./styles.css"], - }, - devtool: "eval-source-map", - stats: "errors-only", - output: { - filename: "[name].[chunkhash].js", - }, - module: { - rules: [ - { - test: /\.tsx?$/, - exclude: /node_modules/, - loader: "babel-loader", - }, - { - test: /\.(png|jpg)$/, - type: "asset/resource", - }, - { - test: /\.html$/, - loader: "html-loader", - }, - { - test: /\.css$/, - exclude: /node_modules/, - use: [ - { - loader: "style-loader", - }, - { - loader: "css-loader", - }, - ], - }, - ], - }, - plugins: [ - //Generate index.html in /dist => https://github.com/ampedandwired/html-webpack-plugin - new HtmlWebpackPlugin({ - filename: "index.html", //Name of file in ./dist/ - template: "index.html", //Name of template in ./src - }), - ], -}; diff --git a/04-frameworks/01-react/03-react-hooks/16-use-debug-value/.babelrc b/04-frameworks/01-react/03-react-hooks/16-use-debug-value/.babelrc deleted file mode 100644 index 469d3d55f..000000000 --- a/04-frameworks/01-react/03-react-hooks/16-use-debug-value/.babelrc +++ /dev/null @@ -1,7 +0,0 @@ -{ - "presets": [ - "@babel/preset-env", - "@babel/preset-typescript", - "@babel/preset-react" - ] -} diff --git a/04-frameworks/01-react/03-react-hooks/16-use-debug-value/index.html b/04-frameworks/01-react/03-react-hooks/16-use-debug-value/index.html new file mode 100644 index 000000000..892c75140 --- /dev/null +++ b/04-frameworks/01-react/03-react-hooks/16-use-debug-value/index.html @@ -0,0 +1,12 @@ + + + + + + React App - React hooks + + +
+ + + diff --git a/04-frameworks/01-react/03-react-hooks/16-use-debug-value/package.json b/04-frameworks/01-react/03-react-hooks/16-use-debug-value/package.json index d434b896c..9ee970f00 100644 --- a/04-frameworks/01-react/03-react-hooks/16-use-debug-value/package.json +++ b/04-frameworks/01-react/03-react-hooks/16-use-debug-value/package.json @@ -1,40 +1,23 @@ { - "name": "react-example", - "version": "1.0.0", - "description": "", - "main": "index.js", + "name": "hello-vite", + "private": true, + "version": "0.0.0", + "type": "module", "scripts": { - "start": "run-p -l type-check:watch start:dev", - "type-check": "tsc --noEmit", - "type-check:watch": "npm run type-check -- --watch", - "start:dev": "webpack-dev-server --mode development --open", - "build": "rimraf dist && webpack --mode development" + "start": "vite --host", + "build": "vite build", + "preview": "vite preview" }, - "author": "", - "license": "ISC", "devDependencies": { - "@babel/cli": "^7.17.10", - "@babel/core": "^7.17.10", - "@babel/preset-env": "^7.17.10", - "@babel/preset-react": "^7.17.12", - "@babel/preset-typescript": "^7.16.7", - "@types/react": "^18.0.9", - "@types/react-dom": "^18.0.4", - "babel-loader": "^8.2.5", - "css-loader": "^6.7.1", - "html-loader": "^3.1.0", - "html-webpack-plugin": "^5.5.0", - "npm-run-all": "^4.1.5", - "rimraf": "^3.0.2", - "style-loader": "^3.3.1", - "typescript": "^4.6.4", - "webpack": "^5.72.1", - "webpack-cli": "^4.9.2", - "webpack-dev-server": "^4.9.0" + "@types/react": "^19.1.8", + "@types/react-dom": "^19.1.6", + "@vitejs/plugin-react": "^4.6.0", + "typescript": "^5.8.3", + "vite": "^7.0.4", + "vite-plugin-checker": "^0.10.0" }, "dependencies": { - "react": "^18.1.0", - "react-dom": "^18.1.0", - "use-debounce": "^8.0.1" + "react": "^19.1.0", + "react-dom": "^19.1.0" } } diff --git a/04-frameworks/01-react/03-react-hooks/16-use-debug-value/src/index.html b/04-frameworks/01-react/03-react-hooks/16-use-debug-value/src/index.html deleted file mode 100644 index a3d74b719..000000000 --- a/04-frameworks/01-react/03-react-hooks/16-use-debug-value/src/index.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - My App Example - - -
- - diff --git a/04-frameworks/01-react/03-react-hooks/16-use-debug-value/src/index.tsx b/04-frameworks/01-react/03-react-hooks/16-use-debug-value/src/index.tsx index 7e439b87e..7c541901b 100644 --- a/04-frameworks/01-react/03-react-hooks/16-use-debug-value/src/index.tsx +++ b/04-frameworks/01-react/03-react-hooks/16-use-debug-value/src/index.tsx @@ -1,6 +1,7 @@ import React from "react"; import { createRoot } from "react-dom/client"; import { App } from "./app"; +import "./styles.css"; const container = document.getElementById("root"); const root = createRoot(container); diff --git a/04-frameworks/01-react/03-react-hooks/16-use-debug-value/tsconfig.json b/04-frameworks/01-react/03-react-hooks/16-use-debug-value/tsconfig.json index 3312b5f1e..a057cea1d 100644 --- a/04-frameworks/01-react/03-react-hooks/16-use-debug-value/tsconfig.json +++ b/04-frameworks/01-react/03-react-hooks/16-use-debug-value/tsconfig.json @@ -1,18 +1,19 @@ { "compilerOptions": { - "target": "es6", - "module": "es6", - "moduleResolution": "node", - "declaration": false, + "esModuleInterop": true, + "isolatedModules": true, + "jsx": "react-jsx", + "lib": ["ESNext", "DOM"], + "module": "ESNext", + "moduleResolution": "bundler", + "noEmit": true, "noImplicitAny": false, - "allowSyntheticDefaultImports": true, - "sourceMap": true, - "jsx": "react", - "noLib": false, - "suppressImplicitAnyIndexErrors": true, + "noImplicitReturns": true, + "resolveJsonModule": true, "skipLibCheck": true, - "esModuleInterop": true + "sourceMap": true, + "target": "ESNext", + "useDefineForClassFields": true }, - "include": ["src/**/*"], - "exclude": ["node_modules"] + "include": ["src"] } diff --git a/04-frameworks/01-react/03-react-hooks/16-use-debug-value/vite.config.ts b/04-frameworks/01-react/03-react-hooks/16-use-debug-value/vite.config.ts new file mode 100644 index 000000000..a0024d88e --- /dev/null +++ b/04-frameworks/01-react/03-react-hooks/16-use-debug-value/vite.config.ts @@ -0,0 +1,7 @@ +import { defineConfig } from "vite"; +import checker from "vite-plugin-checker"; +import react from "@vitejs/plugin-react"; + +export default defineConfig({ + plugins: [checker({ typescript: true }), react()], +}); diff --git a/04-frameworks/01-react/03-react-hooks/16-use-debug-value/webpack.config.js b/04-frameworks/01-react/03-react-hooks/16-use-debug-value/webpack.config.js deleted file mode 100644 index 326060f82..000000000 --- a/04-frameworks/01-react/03-react-hooks/16-use-debug-value/webpack.config.js +++ /dev/null @@ -1,54 +0,0 @@ -const HtmlWebpackPlugin = require("html-webpack-plugin"); -const path = require("path"); -const basePath = __dirname; - -module.exports = { - context: path.join(basePath, "src"), - resolve: { - extensions: [".js", ".ts", ".tsx"], - }, - entry: { - app: ["./index.tsx", "./styles.css"], - }, - devtool: "eval-source-map", - stats: "errors-only", - output: { - filename: "[name].[chunkhash].js", - }, - module: { - rules: [ - { - test: /\.tsx?$/, - exclude: /node_modules/, - loader: "babel-loader", - }, - { - test: /\.(png|jpg)$/, - type: "asset/resource", - }, - { - test: /\.html$/, - loader: "html-loader", - }, - { - test: /\.css$/, - exclude: /node_modules/, - use: [ - { - loader: "style-loader", - }, - { - loader: "css-loader", - }, - ], - }, - ], - }, - plugins: [ - //Generate index.html in /dist => https://github.com/ampedandwired/html-webpack-plugin - new HtmlWebpackPlugin({ - filename: "index.html", //Name of file in ./dist/ - template: "index.html", //Name of template in ./src - }), - ], -}; diff --git a/04-frameworks/01-react/03-react-hooks/17-why-did-you-update/.babelrc b/04-frameworks/01-react/03-react-hooks/17-why-did-you-update/.babelrc deleted file mode 100644 index 469d3d55f..000000000 --- a/04-frameworks/01-react/03-react-hooks/17-why-did-you-update/.babelrc +++ /dev/null @@ -1,7 +0,0 @@ -{ - "presets": [ - "@babel/preset-env", - "@babel/preset-typescript", - "@babel/preset-react" - ] -} diff --git a/04-frameworks/01-react/03-react-hooks/17-why-did-you-update/index.html b/04-frameworks/01-react/03-react-hooks/17-why-did-you-update/index.html new file mode 100644 index 000000000..892c75140 --- /dev/null +++ b/04-frameworks/01-react/03-react-hooks/17-why-did-you-update/index.html @@ -0,0 +1,12 @@ + + + + + + React App - React hooks + + +
+ + + diff --git a/04-frameworks/01-react/03-react-hooks/17-why-did-you-update/package.json b/04-frameworks/01-react/03-react-hooks/17-why-did-you-update/package.json index d434b896c..9ee970f00 100644 --- a/04-frameworks/01-react/03-react-hooks/17-why-did-you-update/package.json +++ b/04-frameworks/01-react/03-react-hooks/17-why-did-you-update/package.json @@ -1,40 +1,23 @@ { - "name": "react-example", - "version": "1.0.0", - "description": "", - "main": "index.js", + "name": "hello-vite", + "private": true, + "version": "0.0.0", + "type": "module", "scripts": { - "start": "run-p -l type-check:watch start:dev", - "type-check": "tsc --noEmit", - "type-check:watch": "npm run type-check -- --watch", - "start:dev": "webpack-dev-server --mode development --open", - "build": "rimraf dist && webpack --mode development" + "start": "vite --host", + "build": "vite build", + "preview": "vite preview" }, - "author": "", - "license": "ISC", "devDependencies": { - "@babel/cli": "^7.17.10", - "@babel/core": "^7.17.10", - "@babel/preset-env": "^7.17.10", - "@babel/preset-react": "^7.17.12", - "@babel/preset-typescript": "^7.16.7", - "@types/react": "^18.0.9", - "@types/react-dom": "^18.0.4", - "babel-loader": "^8.2.5", - "css-loader": "^6.7.1", - "html-loader": "^3.1.0", - "html-webpack-plugin": "^5.5.0", - "npm-run-all": "^4.1.5", - "rimraf": "^3.0.2", - "style-loader": "^3.3.1", - "typescript": "^4.6.4", - "webpack": "^5.72.1", - "webpack-cli": "^4.9.2", - "webpack-dev-server": "^4.9.0" + "@types/react": "^19.1.8", + "@types/react-dom": "^19.1.6", + "@vitejs/plugin-react": "^4.6.0", + "typescript": "^5.8.3", + "vite": "^7.0.4", + "vite-plugin-checker": "^0.10.0" }, "dependencies": { - "react": "^18.1.0", - "react-dom": "^18.1.0", - "use-debounce": "^8.0.1" + "react": "^19.1.0", + "react-dom": "^19.1.0" } } diff --git a/04-frameworks/01-react/03-react-hooks/17-why-did-you-update/src/demo.tsx b/04-frameworks/01-react/03-react-hooks/17-why-did-you-update/src/demo.tsx index 1ce9a88cb..7c2886cc9 100644 --- a/04-frameworks/01-react/03-react-hooks/17-why-did-you-update/src/demo.tsx +++ b/04-frameworks/01-react/03-react-hooks/17-why-did-you-update/src/demo.tsx @@ -4,7 +4,7 @@ import React from "react"; function useWhyDidYouUpdate(name, props) { // Get a mutable ref object where we can store props ... // ... for comparison next time this hook runs. - const previousProps = React.useRef(); + const previousProps = React.useRef(null); React.useEffect(() => { if (previousProps.current) { diff --git a/04-frameworks/01-react/03-react-hooks/17-why-did-you-update/src/index.html b/04-frameworks/01-react/03-react-hooks/17-why-did-you-update/src/index.html deleted file mode 100644 index a3d74b719..000000000 --- a/04-frameworks/01-react/03-react-hooks/17-why-did-you-update/src/index.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - My App Example - - -
- - diff --git a/04-frameworks/01-react/03-react-hooks/17-why-did-you-update/tsconfig.json b/04-frameworks/01-react/03-react-hooks/17-why-did-you-update/tsconfig.json index 3312b5f1e..a057cea1d 100644 --- a/04-frameworks/01-react/03-react-hooks/17-why-did-you-update/tsconfig.json +++ b/04-frameworks/01-react/03-react-hooks/17-why-did-you-update/tsconfig.json @@ -1,18 +1,19 @@ { "compilerOptions": { - "target": "es6", - "module": "es6", - "moduleResolution": "node", - "declaration": false, + "esModuleInterop": true, + "isolatedModules": true, + "jsx": "react-jsx", + "lib": ["ESNext", "DOM"], + "module": "ESNext", + "moduleResolution": "bundler", + "noEmit": true, "noImplicitAny": false, - "allowSyntheticDefaultImports": true, - "sourceMap": true, - "jsx": "react", - "noLib": false, - "suppressImplicitAnyIndexErrors": true, + "noImplicitReturns": true, + "resolveJsonModule": true, "skipLibCheck": true, - "esModuleInterop": true + "sourceMap": true, + "target": "ESNext", + "useDefineForClassFields": true }, - "include": ["src/**/*"], - "exclude": ["node_modules"] + "include": ["src"] } diff --git a/04-frameworks/01-react/03-react-hooks/17-why-did-you-update/vite.config.ts b/04-frameworks/01-react/03-react-hooks/17-why-did-you-update/vite.config.ts new file mode 100644 index 000000000..a0024d88e --- /dev/null +++ b/04-frameworks/01-react/03-react-hooks/17-why-did-you-update/vite.config.ts @@ -0,0 +1,7 @@ +import { defineConfig } from "vite"; +import checker from "vite-plugin-checker"; +import react from "@vitejs/plugin-react"; + +export default defineConfig({ + plugins: [checker({ typescript: true }), react()], +}); diff --git a/04-frameworks/01-react/03-react-hooks/17-why-did-you-update/webpack.config.js b/04-frameworks/01-react/03-react-hooks/17-why-did-you-update/webpack.config.js deleted file mode 100644 index 326060f82..000000000 --- a/04-frameworks/01-react/03-react-hooks/17-why-did-you-update/webpack.config.js +++ /dev/null @@ -1,54 +0,0 @@ -const HtmlWebpackPlugin = require("html-webpack-plugin"); -const path = require("path"); -const basePath = __dirname; - -module.exports = { - context: path.join(basePath, "src"), - resolve: { - extensions: [".js", ".ts", ".tsx"], - }, - entry: { - app: ["./index.tsx", "./styles.css"], - }, - devtool: "eval-source-map", - stats: "errors-only", - output: { - filename: "[name].[chunkhash].js", - }, - module: { - rules: [ - { - test: /\.tsx?$/, - exclude: /node_modules/, - loader: "babel-loader", - }, - { - test: /\.(png|jpg)$/, - type: "asset/resource", - }, - { - test: /\.html$/, - loader: "html-loader", - }, - { - test: /\.css$/, - exclude: /node_modules/, - use: [ - { - loader: "style-loader", - }, - { - loader: "css-loader", - }, - ], - }, - ], - }, - plugins: [ - //Generate index.html in /dist => https://github.com/ampedandwired/html-webpack-plugin - new HtmlWebpackPlugin({ - filename: "index.html", //Name of file in ./dist/ - template: "index.html", //Name of template in ./src - }), - ], -}; diff --git a/04-frameworks/01-react/03-react-hooks/18-use-promise/Readme_es.md b/04-frameworks/01-react/03-react-hooks/18-use-promise/Readme_es.md new file mode 100644 index 000000000..35dd3f49f --- /dev/null +++ b/04-frameworks/01-react/03-react-hooks/18-use-promise/Readme_es.md @@ -0,0 +1,278 @@ +# 06 Use hook + +Vamos a ver el nuevo hook _use_, introducido en la versión 19 de react. En este ejemplo vamos a usar el hook para consumir datos que recibimos de manera asíncrona, haciendo una petición al servidor. + +## Punto de Partida + +Este ejemplo parte del ejercicio _06-ajax-field-change_. Si no tienes el código a mano te lo dejamos por aquí. + +_./src/demo.tsx_ + +```tsx +import React from "react"; + +export const MyComponent = () => { + const [filter, setFilter] = React.useState(""); + const [userCollection, setUserCollection] = React.useState([]); + + React.useEffect(() => { + fetch(`https://jsonplaceholder.typicode.com/users?name_like=${filter}`) + .then((response) => response.json()) + .then((json) => setUserCollection(json)); + }, [filter]); + + return ( +
+ setFilter(e.target.value)} /> + +
+ ); +}; +``` + +_./src/app.tsx_ + +```tsx +import React from "react"; +import { MyComponent } from "./demo"; + +export const App = () => { + return ; +}; +``` + +## Paso a Paso + +Primero hacemos un _npm install_. + +```bash +npm install +``` + +Lo primero que necesitamos es una llamada asíncrona. Vamos a crearnos por el momento una llamada que no ataque a ningún servidor, sino que simplemente devuelva usuarios mockeados. Introducimos además un log para ver cuantas veces se ejecuta la función. + +En _./src/demo.tsx_ + +```diff +import React from "react"; + ++ const fetchMockedUsers = async () => { ++ console.log("executed"); ++ const res = await Promise.resolve([{ name: "Test user", id: 1 }]); ++ return res; ++ }; + +export const MyComponent = () => { +``` + +El hook use se va a encargar de gestionar la llamada y de devolvernos el estado, por lo que podemos reemplazar el useState y el useEffect. + +En _./src/demo.tsx_ + +```diff +- import React from "react"; ++ import React, { use } from "react"; + + +export const MyComponent = () => { + const [filter, setFilter] = React.useState(""); ++ const userCollection = use(fetchMockedUsers()) +- const [userCollection, setUserCollection] = React.useState([]); + +- React.useEffect(() => { +- fetch(`https://jsonplaceholder.typicode.com/users?name_like=${filter}`) +- .then((response) => response.json()) +- .then((json) => setUserCollection(json)); +- }, [filter]); + + return ( +``` + +Si levantamos el proyecto, abrimos las _devTools_ y vemos los logs del browser, nos damos cuenta de que hemos entrado en un bucle infinito (el log aparece muchas veces). Esto se debe a como funciona el hook _use_ por dentro y a que nos hemos saltado una regla fundamental establecida por la documentación de React: al hook _use_ hay que pasarle una referencia estable. +Esto se diferencia a lo que hemos hecho dentro de nuestro componente, donde dentro de cada ejecución _fetchMockedUsers()_ crea una nueva referencia en cada re-ejecución, por lo que el componente se va a re-ejecutar infinitas veces. + +Para poder adaptarnos a las condiciones de uso de _use_ esa referencia debe ser estable, por lo que le deberá llegar a nuestro componente como _prop_. De esta manera esa _prop_ no se calculará en cada ejecución. + +Así, nos creamos un componente padre _MyParentComponent_ que wrapee a _MyComponent_. + +- Movemos _fetchMockedUsers_ a este fichero +- Creamos User interface. +- Introducimos _Suspense_, requerido para poder usar _use_. Este componente nos permitirá usar un fallback mientras la llamada está pendiente de resolverse. + +_./src/parent.tsx_ + +```tsx +import React, { Suspense } from "react"; +import { MyComponent } from "./demo"; + +export interface User { + id: number; + name: string; +} + +const fetchMockedUsers = async () => { + console.log("executed"); + const res = await Promise.resolve([{ name: "Test user", id: 1 }]); + return res; +}; + +export const MyParentComponent = () => { + const mockedUsersPromise = fetchMockedUsers(); + return ( + <> + Loading}> + + + + ); +}; +``` + +Actualizamos en _./src/demo.tsx_: + +- Tipamos _MyComponent_ correctamente. +- _MyComponent_ recibe la nueva prop. +- Eliminamos _fetchMockedUsers_. + +```diff +import React, { use } from "react"; ++ import { User } from './parent'; + +- export const fetchMockedUsers = async () => { +- console.log("executed"); +- const res = await Promise.resolve([{ name: "Test user", id: 1 }]); +- return res; +- }; + ++ interface MyComponentProps { ++ userPromise: Promise ++ } + +- export const MyComponent = () => { ++ export const MyComponent: React.FC = ({ userPromise }) => { + const [filter, setFilter] = React.useState(""); +- const userCollection = use(fetchMockedUsers()); ++ const userCollection = use(userPromise); + + return ( +``` + +Reemplazamos en _./src/app.tsx_ + +```diff +import React from "react"; +- import { MyComponent } from "./demo"; ++ import { MyParentComponent } from "./parent"; + +export const App = () => { +- return ; ++ return ; +}; +``` + +Comprobamos que la aplicación funciona. + +Ahora que ya sabemos que no estamos incurriendo en bucles infinitos es seguro sustituir la función mock por la llamada real. Además, al estar interpolando dentro de la llamada _filter_, nos tenemos que traer el estado y el input que lo setea. + +_./src/parent.tsx_ + +```diff +export interface User { + id: number; + name: string; +} + +- const fetchMockedUsers = async () => { +- console.log("executed"); +- const res = await Promise.resolve([{ name: "Test user", id: 1 }]); +- return res; +- }; + ++ const fetchUsers = async (filter): Promise => { ++ const res = await fetch( ++ `https://jsonplaceholder.typicode.com/users?name_like=${filter}` ++ ); ++ return res.json(); ++ }; + +export const MyParentComponent = () => { ++ const [filter, setFilter] = React.useState(""); +- const mockedUsersPromise = fetchMockedUsers(); ++ const usersPromise = fetchUsers(filter); + + return ( + <> ++ setFilter(e.target.value)} /> + Loading}> +- ++ + + + ); +}; +``` + +Eliminamos de _MyComponent_, el estado _filter_ y el input que lo setea: + +_./src/demo.tsx_ + +```diff +export const MyComponent: React.FC = ({ userPromise }) => { +- const [filter, setFilter] = React.useState(""); + const userCollection = use(userPromise); + + return ( +
+- setFilter(e.target.value)} /> +
    +``` + +Y si quisiéramos implementar el useDebounce? + +- Instalamos la librería _use-debounce_ como dependencia + +```bash +npm i use-debounce +``` + +En _./src/parent.tsx_: + +```diff +import React, { Suspense } from "react"; ++ import { useDebounce } from "use-debounce"; + +(...) + +export const MyParentComponent = () => { + const [filter, setFilter] = React.useState(""); ++ const [debouncedFilter] = useDebounce(filter, 1500); +- const usersPromise = fetchUsers(filter); + ++ const usersPromise = React.useMemo( ++ () => fetchUsers(debouncedFilter), ++ [debouncedFilter] ++ ); + + return ( + <> ++
    Debounced filter: {debouncedFilter}
    + setFilter(e.target.value)} /> + Loading}> +``` + +# ¿Te apuntas a nuestro máster? + +Si te ha gustado este ejemplo y tienes ganas de aprender Front End +guiado por un grupo de profesionales ¿Por qué no te apuntas a +nuestro [Máster Front End Online Lemoncode](https://lemoncode.net/master-frontend#inicio-banner)? Tenemos tanto edición de convocatoria +con clases en vivo, como edición continua con mentorización, para +que puedas ir a tu ritmo y aprender mucho. + +Si lo que te gusta es el mundo del _backend_ también puedes apuntante a nuestro [Bootcamp backend Online Lemoncode](https://lemoncode.net/bootcamp-backend#bootcamp-backend/inicio) + +Y si tienes ganas de meterte una zambullida en el mundo _devops_ +apuntate nuestro [Bootcamp devops online Lemoncode](https://lemoncode.net/bootcamp-devops#bootcamp-devops/inicio) diff --git a/04-frameworks/01-react/03-react-hooks/18-use-promise/index.html b/04-frameworks/01-react/03-react-hooks/18-use-promise/index.html new file mode 100644 index 000000000..892c75140 --- /dev/null +++ b/04-frameworks/01-react/03-react-hooks/18-use-promise/index.html @@ -0,0 +1,12 @@ + + + + + + React App - React hooks + + +
    + + + diff --git a/04-frameworks/01-react/03-react-hooks/18-use-promise/package.json b/04-frameworks/01-react/03-react-hooks/18-use-promise/package.json new file mode 100644 index 000000000..cb10a2306 --- /dev/null +++ b/04-frameworks/01-react/03-react-hooks/18-use-promise/package.json @@ -0,0 +1,24 @@ +{ + "name": "hello-vite", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "start": "vite --host", + "build": "vite build", + "preview": "vite preview" + }, + "devDependencies": { + "@types/react": "^19.1.8", + "@types/react-dom": "^19.1.6", + "@vitejs/plugin-react": "^4.6.0", + "typescript": "^5.8.3", + "vite": "^7.0.4", + "vite-plugin-checker": "^0.10.0" + }, + "dependencies": { + "react": "^19.1.0", + "react-dom": "^19.1.0", + "use-debounce": "^10.0.5" + } +} diff --git a/04-frameworks/01-react/03-react-hooks/18-use-promise/src/app.tsx b/04-frameworks/01-react/03-react-hooks/18-use-promise/src/app.tsx new file mode 100644 index 000000000..69c1d3337 --- /dev/null +++ b/04-frameworks/01-react/03-react-hooks/18-use-promise/src/app.tsx @@ -0,0 +1,6 @@ +import React from "react"; +import { MyParentComponent } from "./parent"; + +export const App = () => { + return ; +}; diff --git a/04-frameworks/01-react/03-react-hooks/18-use-promise/src/demo.tsx b/04-frameworks/01-react/03-react-hooks/18-use-promise/src/demo.tsx new file mode 100644 index 000000000..de7b9d074 --- /dev/null +++ b/04-frameworks/01-react/03-react-hooks/18-use-promise/src/demo.tsx @@ -0,0 +1,20 @@ +import React, { use } from "react"; +import { User } from "./parent"; + +interface MyComponentProps { + userPromise: Promise; +} + +export const MyComponent: React.FC = ({ userPromise }) => { + const userCollection = use(userPromise); + + return ( +
    +
      + {userCollection.map((user, index) => ( +
    • {user.name}
    • + ))} +
    +
    + ); +}; diff --git a/04-frameworks/01-react/03-react-hooks/18-use-promise/src/index.tsx b/04-frameworks/01-react/03-react-hooks/18-use-promise/src/index.tsx new file mode 100644 index 000000000..7e439b87e --- /dev/null +++ b/04-frameworks/01-react/03-react-hooks/18-use-promise/src/index.tsx @@ -0,0 +1,8 @@ +import React from "react"; +import { createRoot } from "react-dom/client"; +import { App } from "./app"; + +const container = document.getElementById("root"); +const root = createRoot(container); + +root.render(); diff --git a/04-frameworks/01-react/03-react-hooks/18-use-promise/src/parent.tsx b/04-frameworks/01-react/03-react-hooks/18-use-promise/src/parent.tsx new file mode 100644 index 000000000..24c7bb748 --- /dev/null +++ b/04-frameworks/01-react/03-react-hooks/18-use-promise/src/parent.tsx @@ -0,0 +1,34 @@ +import React, { Suspense } from "react"; +import { useDebounce } from "use-debounce"; +import { MyComponent } from "./demo"; + +export interface User { + id: number; + name: string; +} + +const fetchUsers = async (filter): Promise => { + const res = await fetch( + `https://jsonplaceholder.typicode.com/users?name_like=${filter}` + ); + return res.json(); +}; + +export const MyParentComponent = () => { + const [filter, setFilter] = React.useState(""); + const [debouncedFilter] = useDebounce(filter, 1500); + + const usersPromise = React.useMemo( + () => fetchUsers(debouncedFilter), + [debouncedFilter] + ); + + return ( + <> + setFilter(e.target.value)} /> + Loading}> + + + + ); +}; diff --git a/04-frameworks/01-react/03-react-hooks/18-use-promise/src/styles.css b/04-frameworks/01-react/03-react-hooks/18-use-promise/src/styles.css new file mode 100644 index 000000000..74dc08fbb --- /dev/null +++ b/04-frameworks/01-react/03-react-hooks/18-use-promise/src/styles.css @@ -0,0 +1,3 @@ +.my-text { + color: blue; +} diff --git a/04-frameworks/01-react/03-react-hooks/18-use-promise/tsconfig.json b/04-frameworks/01-react/03-react-hooks/18-use-promise/tsconfig.json new file mode 100644 index 000000000..a057cea1d --- /dev/null +++ b/04-frameworks/01-react/03-react-hooks/18-use-promise/tsconfig.json @@ -0,0 +1,19 @@ +{ + "compilerOptions": { + "esModuleInterop": true, + "isolatedModules": true, + "jsx": "react-jsx", + "lib": ["ESNext", "DOM"], + "module": "ESNext", + "moduleResolution": "bundler", + "noEmit": true, + "noImplicitAny": false, + "noImplicitReturns": true, + "resolveJsonModule": true, + "skipLibCheck": true, + "sourceMap": true, + "target": "ESNext", + "useDefineForClassFields": true + }, + "include": ["src"] +} diff --git a/04-frameworks/01-react/03-react-hooks/18-use-promise/vite.config.ts b/04-frameworks/01-react/03-react-hooks/18-use-promise/vite.config.ts new file mode 100644 index 000000000..a0024d88e --- /dev/null +++ b/04-frameworks/01-react/03-react-hooks/18-use-promise/vite.config.ts @@ -0,0 +1,7 @@ +import { defineConfig } from "vite"; +import checker from "vite-plugin-checker"; +import react from "@vitejs/plugin-react"; + +export default defineConfig({ + plugins: [checker({ typescript: true }), react()], +}); diff --git a/04-frameworks/01-react/03-react-hooks/99-promise-unmounted-R17/.babelrc b/04-frameworks/01-react/03-react-hooks/99-promise-unmounted-R17/.babelrc deleted file mode 100644 index 469d3d55f..000000000 --- a/04-frameworks/01-react/03-react-hooks/99-promise-unmounted-R17/.babelrc +++ /dev/null @@ -1,7 +0,0 @@ -{ - "presets": [ - "@babel/preset-env", - "@babel/preset-typescript", - "@babel/preset-react" - ] -} diff --git a/04-frameworks/01-react/03-react-hooks/99-promise-unmounted-R17/Readme.md b/04-frameworks/01-react/03-react-hooks/99-promise-unmounted-R17/Readme.md index aa2a6c825..f607e3e7e 100644 --- a/04-frameworks/01-react/03-react-hooks/99-promise-unmounted-R17/Readme.md +++ b/04-frameworks/01-react/03-react-hooks/99-promise-unmounted-R17/Readme.md @@ -1,6 +1,6 @@ # 15 Promise unmounted -## Resume +## Summary This example takes as a starting point the example _14-use-ref-dom_. @@ -63,7 +63,7 @@ export const MyChildComponent = () => { - Now we want to launch an ajax request every time the user writes in the filter's text field (we'll add some latency). -_./src/demo.js_ +_./src/demo.tsx_ ```diff export const MyChildComponent = () => { diff --git a/04-frameworks/01-react/03-react-hooks/99-promise-unmounted-R17/Readme_es.md b/04-frameworks/01-react/03-react-hooks/99-promise-unmounted-R17/Readme_es.md index d755c4003..5e0597848 100644 --- a/04-frameworks/01-react/03-react-hooks/99-promise-unmounted-R17/Readme_es.md +++ b/04-frameworks/01-react/03-react-hooks/99-promise-unmounted-R17/Readme_es.md @@ -28,7 +28,7 @@ npm install Primero creamos el armazon -_./src/demo.js_ +_./src/demo.tsx_ ```tsx import React from "react"; @@ -65,7 +65,7 @@ export const MyChildComponent = () => { - Ahora queremos lanzar una petición ajax cada vez que el usuario escriba en el campo de texto del filtro (añadiremos algo de latencia). -_./src/demo.js_ +_./src/demo.tsx_ ```diff export const MyChildComponent = () => { diff --git a/04-frameworks/01-react/03-react-hooks/99-promise-unmounted-R17/index.html b/04-frameworks/01-react/03-react-hooks/99-promise-unmounted-R17/index.html new file mode 100644 index 000000000..892c75140 --- /dev/null +++ b/04-frameworks/01-react/03-react-hooks/99-promise-unmounted-R17/index.html @@ -0,0 +1,12 @@ + + + + + + React App - React hooks + + +
    + + + diff --git a/04-frameworks/01-react/03-react-hooks/99-promise-unmounted-R17/package.json b/04-frameworks/01-react/03-react-hooks/99-promise-unmounted-R17/package.json index d434b896c..9ee970f00 100644 --- a/04-frameworks/01-react/03-react-hooks/99-promise-unmounted-R17/package.json +++ b/04-frameworks/01-react/03-react-hooks/99-promise-unmounted-R17/package.json @@ -1,40 +1,23 @@ { - "name": "react-example", - "version": "1.0.0", - "description": "", - "main": "index.js", + "name": "hello-vite", + "private": true, + "version": "0.0.0", + "type": "module", "scripts": { - "start": "run-p -l type-check:watch start:dev", - "type-check": "tsc --noEmit", - "type-check:watch": "npm run type-check -- --watch", - "start:dev": "webpack-dev-server --mode development --open", - "build": "rimraf dist && webpack --mode development" + "start": "vite --host", + "build": "vite build", + "preview": "vite preview" }, - "author": "", - "license": "ISC", "devDependencies": { - "@babel/cli": "^7.17.10", - "@babel/core": "^7.17.10", - "@babel/preset-env": "^7.17.10", - "@babel/preset-react": "^7.17.12", - "@babel/preset-typescript": "^7.16.7", - "@types/react": "^18.0.9", - "@types/react-dom": "^18.0.4", - "babel-loader": "^8.2.5", - "css-loader": "^6.7.1", - "html-loader": "^3.1.0", - "html-webpack-plugin": "^5.5.0", - "npm-run-all": "^4.1.5", - "rimraf": "^3.0.2", - "style-loader": "^3.3.1", - "typescript": "^4.6.4", - "webpack": "^5.72.1", - "webpack-cli": "^4.9.2", - "webpack-dev-server": "^4.9.0" + "@types/react": "^19.1.8", + "@types/react-dom": "^19.1.6", + "@vitejs/plugin-react": "^4.6.0", + "typescript": "^5.8.3", + "vite": "^7.0.4", + "vite-plugin-checker": "^0.10.0" }, "dependencies": { - "react": "^18.1.0", - "react-dom": "^18.1.0", - "use-debounce": "^8.0.1" + "react": "^19.1.0", + "react-dom": "^19.1.0" } } diff --git a/04-frameworks/01-react/03-react-hooks/99-promise-unmounted-R17/src/index.html b/04-frameworks/01-react/03-react-hooks/99-promise-unmounted-R17/src/index.html deleted file mode 100644 index a3d74b719..000000000 --- a/04-frameworks/01-react/03-react-hooks/99-promise-unmounted-R17/src/index.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - My App Example - - -
    - - diff --git a/04-frameworks/01-react/03-react-hooks/99-promise-unmounted-R17/tsconfig.json b/04-frameworks/01-react/03-react-hooks/99-promise-unmounted-R17/tsconfig.json index 3312b5f1e..a057cea1d 100644 --- a/04-frameworks/01-react/03-react-hooks/99-promise-unmounted-R17/tsconfig.json +++ b/04-frameworks/01-react/03-react-hooks/99-promise-unmounted-R17/tsconfig.json @@ -1,18 +1,19 @@ { "compilerOptions": { - "target": "es6", - "module": "es6", - "moduleResolution": "node", - "declaration": false, + "esModuleInterop": true, + "isolatedModules": true, + "jsx": "react-jsx", + "lib": ["ESNext", "DOM"], + "module": "ESNext", + "moduleResolution": "bundler", + "noEmit": true, "noImplicitAny": false, - "allowSyntheticDefaultImports": true, - "sourceMap": true, - "jsx": "react", - "noLib": false, - "suppressImplicitAnyIndexErrors": true, + "noImplicitReturns": true, + "resolveJsonModule": true, "skipLibCheck": true, - "esModuleInterop": true + "sourceMap": true, + "target": "ESNext", + "useDefineForClassFields": true }, - "include": ["src/**/*"], - "exclude": ["node_modules"] + "include": ["src"] } diff --git a/04-frameworks/01-react/03-react-hooks/99-promise-unmounted-R17/vite.config.ts b/04-frameworks/01-react/03-react-hooks/99-promise-unmounted-R17/vite.config.ts new file mode 100644 index 000000000..a0024d88e --- /dev/null +++ b/04-frameworks/01-react/03-react-hooks/99-promise-unmounted-R17/vite.config.ts @@ -0,0 +1,7 @@ +import { defineConfig } from "vite"; +import checker from "vite-plugin-checker"; +import react from "@vitejs/plugin-react"; + +export default defineConfig({ + plugins: [checker({ typescript: true }), react()], +}); diff --git a/04-frameworks/01-react/03-react-hooks/99-promise-unmounted-R17/webpack.config.js b/04-frameworks/01-react/03-react-hooks/99-promise-unmounted-R17/webpack.config.js deleted file mode 100644 index 326060f82..000000000 --- a/04-frameworks/01-react/03-react-hooks/99-promise-unmounted-R17/webpack.config.js +++ /dev/null @@ -1,54 +0,0 @@ -const HtmlWebpackPlugin = require("html-webpack-plugin"); -const path = require("path"); -const basePath = __dirname; - -module.exports = { - context: path.join(basePath, "src"), - resolve: { - extensions: [".js", ".ts", ".tsx"], - }, - entry: { - app: ["./index.tsx", "./styles.css"], - }, - devtool: "eval-source-map", - stats: "errors-only", - output: { - filename: "[name].[chunkhash].js", - }, - module: { - rules: [ - { - test: /\.tsx?$/, - exclude: /node_modules/, - loader: "babel-loader", - }, - { - test: /\.(png|jpg)$/, - type: "asset/resource", - }, - { - test: /\.html$/, - loader: "html-loader", - }, - { - test: /\.css$/, - exclude: /node_modules/, - use: [ - { - loader: "style-loader", - }, - { - loader: "css-loader", - }, - ], - }, - ], - }, - plugins: [ - //Generate index.html in /dist => https://github.com/ampedandwired/html-webpack-plugin - new HtmlWebpackPlugin({ - filename: "index.html", //Name of file in ./dist/ - template: "index.html", //Name of template in ./src - }), - ], -};