分类 前端 下的文章

redux将所有数据存储到树中,且树是唯一的。

Redux基本概念

  • store:存储树结构。
  • state:维护的数据,一般维护成树的结构。
  • reducer:对state进行更新的函数,每个state绑定一个reducer。传入两个参数:当前stateaction,返回新state
  • action:一个普通对象,存储reducer的传入参数,一般描述对state的更新类型。
  • dispatch:传入一个参数action,对整棵state树操作一遍。

    React-Redux基本概念

  • Provider组件:用来包裹整个项目,其store属性用来存储reduxstore对象。
  • connect(mapStateToProps, mapDispatchToProps)函数:用来将store与组件关联起来。

    • mapStateToProps:每次store中的状态更新后调用一次,用来更新组件中的值。
    • mapDispatchToProps:组件创建时调用一次,用来将storedispatch函数传入组件。

安装

npm i redux react-redux @reduxjs/toolkit

使用

导入包

在定义store的jsx中导入,当然如果是写在一个文件中就没关系

import { configureStore } from "@reduxjs/toolkit";

在main.jsx/index.jsx中导入Provider

import { Provider } from 'react-redux';

在每一个需要使用到redux全局变量的组件内部导入connect

import { connect } from 'react-redux';

定义actions

可以单独写一个文件,中放一个对象的全局变量来存actions

定义reducer

reducer是一个函数,需要传入两个参数,一个是state,另外一个是action
action是一个对象,state是当前存的数据,需要赋一个初值
例如:

const reducer = (state="0", action) => {
    switch(action.type) {
    }
};

state同时可以维护一个对象,此时reducer可以这样写

const reducer = (state={
    currentOperand: "",
    lastOperand: "",
    operation: "",
}, action) => {
    switch(action.type) {
        default:
            return state;
    }
};

定义store

const store = configureStore({
    reducer: reducer
});

store 和两个reducer的名称可以任意,自己知道就行。
这里reducer和reducer重名,可以只写一个reducer来表示reducer: reducer

例如:

const store = configureStore({
    reducer
});

使用store

在main.jsx/index.jsx中将有使用redux的组件用<Provider></Provider>括起来,同时需要给Provider传一个参数store,就是我们定义的store

例如:

  <Provider store={store}>
    <BrowserRouter>
      <App />
    </BrowserRouter>
  </Provider>

mapDispatchToProps

将dispatch函数绑定到组件上

mapDispatchToProps函数定义

例如:

const mapDispatchToProps = {
    add_digit: digit => {
        return {
            type: ACTIONS.ADD_DIGIT,
            digit: digit,
        }
    }
}

使用connect组件绑定

例如:

export default connect(null, mapDispatchToProps)(DigitButton);

之后就可以通过 this.props.add_digit 来使用add_digit函数了

mapStateToProps

将state数据绑定到组件上

mapStateToProps函数定义

例如:

const mapStateToProps = (state, props) => {
    return {
        currentOperand: state.currentOperand,
        lastOperand: state.lastOperand,
        operation: state.operation,
    }
}

使用connect组件绑定

例如

export default connect(mapStateToProps)(Calculator);

之后就可以通过 this.props. ...来访问state中的数据了

参考资料: https://stackoverflow.com/questions/79289166/something-is-wrong-with-my-react-installation-node-as-a-whole

问题:当使用 create-react-app时出现如下报错

npm error code ERESOLVE
npm error ERESOLVE unable to resolve dependency tree
npm error
npm error While resolving: [email protected]
npm error Found: [email protected]
npm error node_modules/react
npm error   react@"^19.0.0" from the root project
npm error
npm error Could not resolve dependency:
npm error peer react@"^18.0.0" from @testing-library/[email protected]
npm error node_modules/@testing-library/react
npm error   @testing-library/react@"^13.0.0" from the root project
npm error
npm error Fix the upstream dependency conflict, or retry
npm error this command with --force or --legacy-peer-deps
npm error to accept an incorrect (and potentially broken) dependency resolution.
npm error
npm error
npm error For a full report see:
npm error C:\Users\chira\AppData\Local\npm-cache\_logs\2024-12-17T19_27_59_239Z-eresolve-report.txt
npm error A complete log of this run can be found in: C:\Users\chira\AppData\Local\npm-cache\_logs\2024-12-17T19_27_59_239Z-debug-0.log
`npm install --no-audit --save @testing-library/jest-dom@^5.14.1 @testing-library/react@^13.0.0 @testing-library/user-event@^13.2.1 web-vitals@^2.1.0` failed

原因可能是:

因为 React 上周刚刚更新到 v19,而 testing-library/react 还没有更新他们的依赖项要求。

解决:

使用 Vite 创建一个新的 React 应用程序。

npm create vite@latest

运行之后会让我们选择创建哪种模板,选择react之后再选择使用JavaScript即可。

问题背景

在前端开发中,尤其是本地开发时,我们常常直接通过双击 HTML 文件的方式使用浏览器打开网页,路径通常是 file:// 开头的 URL。例如:

file:///D:/web_study/20241217/index.html

在这种情况下,如果你尝试加载 JavaScript 文件,会遇到以下报错:

报错信息

Access to script at 'file:///D:/web_study/20241217/index.js' from origin 'null' has been blocked by CORS policy: 
Cross origin requests are only supported for protocol schemes: chrome, chrome-extension, chrome-untrusted, data, http, https, isolated-app.

GET file:///D:/web_study/20241217/index.js net::ERR_FAILED

报错解析

  1. CORS 限制:浏览器出于安全考虑,默认启用了同源策略(CORS)。当使用 file:// 协议时,浏览器无法确定源 (origin),因此请求被阻止。
  2. ERR_FAILED:网络请求失败,是因为 CORS 策略拒绝加载 JavaScript 文件。

报错原因

现代浏览器的安全机制 CORS(跨域资源共享) 仅支持以下协议:

  • http / https
  • data
  • chrome-extension
  • 等等

file:// 协议不在允许列表内,因此直接打开 HTML 文件并加载 JavaScript 时会触发错误。

解决方案

方法一:使用本地 HTTP 服务器(推荐)

最根本的解决方法是通过本地 HTTP 服务器运行项目,而不是直接打开 file:// 链接。

1. 使用 VSCode 的 Live Server 插件

  • 安装 Live Server 插件:

    • 打开 VSCode,进入插件市场,搜索 "Live Server" 并安装。
  • 启动 Live Server:

    • 在项目目录下右键点击 index.html 文件,选择 "Open with Live Server"
  • 浏览器自动打开页面,访问地址:

    http://localhost:5500

2. 使用 Python 内置 HTTP 服务器

Python 自带一个简单的 HTTP 服务器,可以在本地快速启动:

  • 打开命令行终端,进入 HTML 文件所在目录:

    cd D:/web_study/20241217
  • 运行以下命令(Python 3.x):

    python -m http.server 8000
  • 在浏览器中访问:

    http://localhost:8000/index.html

3. 使用 Node.js 的 http-server 工具

如果你安装了 Node.js,可以使用 http-server 包:

  • 安装 http-server

    npm install -g http-server
  • 启动服务器:

    http-server
  • 浏览器访问:

    http://localhost:8080

方法二:调整 Chrome 浏览器启动参数(临时解决,不推荐)

这种方法临时禁用浏览器的安全策略,仅适用于测试环境。不要在生产环境使用!

  • 在 Chrome 浏览器启动时添加以下参数:

    chrome.exe --allow-file-access-from-files --disable-web-security
  • 然后重新打开 HTML 文件。

⚠️ 警告:此方法存在安全风险,绕过了浏览器的安全机制,仅用于临时测试。


总结

出现 "Access to script at ... has been blocked by CORS policy" 的错误,通常是因为浏览器默认禁止了通过 file:// 协议加载外部资源。解决这个问题最好的方法是使用本地 HTTP 服务器运行项目,比如:

  • VSCode 的 Live Server 插件
  • Python 内置服务器
  • Node.js 的 http-server 工具

通过这些工具,你可以在本地以 http:// 协议访问文件,解决 CORS 报错问题,提升开发效率。

推荐做法

启动一个本地 HTTP 服务器,这是现代前端开发的标准做法,既安全又高效。


希望这篇文章能帮你解决开发中遇到的 CORS 问题!😊 如果有其他问题,欢迎留言交流。