React 面向组件化编程 - 封装了webpack - npm run build 产生的包的 /static 引用路径问题
React 面向组件化编程
面向对象 ----> 面向模块 ----> 面向组件
套路:
注意:
组件名必须大写开头;
只能有一个根标签;
<input />虚拟DOM 元素必须有结束标签
方式1. 工厂函数组件 (简单组件) ----> 只能定义无状态的组件

function MyComponent(){ // 只能 大写开头,区别于普通函数
return <h2>工厂函数组件(简单组件)</h2>
}
// 渲染函数组件标签
// 内部直接调用 工厂组件函数 得到虚拟组件函数
ReactDOM.render(<MyComponent/>, document.getElementById("outer"))

方式2: ES6 类组件 (复杂组件)
class MyComponent2 extends React.Component {
// 1. 必须继承
// 2. 必须大写开头
// 3. 必须重写 render 方法, 指定 return 返回值
render (){
return <h2>ES6类组件(复杂组件)</h2>
}
}
// 渲染类组件标签
// 内部会自动创建类的实例,并调用其 render() 方法得到需要渲染的虚拟 DOM
ReactDOM.render(<MyComponent/>, document.getElementById("outer"));
// 获取到虚拟 DOM 对象 页面上的 原生 DOM
组件的三大属性:
面试题: 区别一下组件的 props 和 state 属性
相同点: 都是组件实例的对象,用于保存数据
不同点:
state 保存组件自身内部可变化的数据
props 保存从外部传入组件内部的数据,组件内部只读而不修改
- state 对象
是组件对象最终要的 属性,属性值是一个对象 (可以包含多个)
组件被称为 "状态机"
更新状态 从而 更新界面 ----> this.setState({stateName1 : newValue})
this.state 是组件私有的,通过调用 this.setState() 来改变它
this.setState() 每次修改以后,自动调用 this.render 方法,再次渲染组件
可以通过 getInitialState() 方法初始化,在组件的生命周期中仅执行一次
var FavoriteButton=React.createClass({
getInitialState:function(){
return {favorite:false};
},
handleClick:function(event){
this.setState({favorite:!this.state.favorite});
},
render:function(){
var text=this.state.favorite? 'favorite':'un favorite';
return (
<div type='button' onClick={this.handleClick}>
You {text} this. Click to toggle.
</div>
);
}
});
---------------------
作者:CrazyCodeBoy
来源:CSDN
原文:https://blog.csdn.net/fengyuzhengfan/article/details/52185921
版权声明:本文为博主原创文章,转载请附上博文链接!
当 state 更新之后,组件就会重新渲染自己。
render() 方法依赖于 this.props 和 this.state ,
框架会确保渲染出来的 UI 界面总是与输入( this.props 和 this.state )保持一致
实例: iLikeQuQ
class Like extends React.Component { // 组件类
constructor(props){
super(props)
this.state = {isLikeMe: false}
}
// 组件中自定义的方法的 this 默认指向 undefined
// 利用 箭头函数 没有自己的 this 来 在函数内使用 this
// 若要 更新组件的显示,必须使用 组件的 setState()
chgText = ()=>{
// this.state.isLikeMe = !this.state.isLikeMe 无效操作
this.setState({
isLikeMe: !this.state.isLikeMe
})
} render(){
const isLikeMe = this.state.isLikeMe
const text = isLikeMe?"I Like U.":"U Like Me."
return <h2 onClick={this.chgText}>{text}</h2>
}
}
ReactDOM.render(<Like/>, document.getElementById("outer"));
每次点击,改变了 状态,那么就会自动重新调用 render() 方法
props 对象
每个组件只会根据 props 渲染了自己一次,props 是不可变的
<script src="https://cdn.bootcss.com/prop-types/15.6.2/prop-types.js"></script>
class Person extends React.Component {
/**** 默认会执行
constructor (props){
super(props); // props 包含了组件标签的所有属性数据
}
****/ render(){
const {name, age, sex} = this.props;
return ({
<ul>
<li>姓名: {name}</li>
<li>年龄: {age}</li>
<li>性别: {sex}</li>
</ul>
})
}
}
// this.props.xxx // 1. 读取属性名 xxx 对应的 属性值
Person.propTypes = { // 2. 设置 props 中属性的约束条件
name: PropTypes.string.isRequired // 必须传参,且 string
} Person.defaultProps = { // 3. 设置 props 中属性的默认值
age: 18,
sex: "未知"
} /**************************************/
const sun = {
name: "孙悟空",
age: 550,
sex: "男"
} // name 被 isRequired 修饰,必须传,且类型必须为 string
ReactDOM.render(<Person name={sun.name} age={sun.age} sex={sun.sex}/>, document.getElementById("outer")); // ReactDOM.render(<Person {...sun}/>, document.getElementById("outer")); // 简化写法
优化为: (propTypes, defaultProps , state 不需要给实例对象直接调用)
class Person extends React.Component {
// 1. 给组件对象 设置 state 属性
state = {
isLikeMe: false
} // 给类添加 属性,只能 类 内部调用
// 2. 设置 props 中属性的约束条件
static propTypes = {
name: PropTypes.string.isRequired // 必须传参,且 string
} // 3. 设置 props 中属性的默认值
static defaultProps = {
age: 18,
sex: "未知"
} render(){
const {name, age, sex} = this.props;
return ({
<ul>
<li>姓名: {name}</li>
<li>年龄: {age}</li>
<li>性别: {sex}</li>
</ul>
})
}
} /**************************************/
const sun = {
name: "孙悟空",
age: 550,
sex: "男"
} // name 被 isRequired 修饰,必须传,且类型必须为 string
ReactDOM.render(<Person {...sun}/>, document.getElementById("outer")); // 简化写法
refs 对象
// 组件对象 refs 保存的是 ref 关联的虚拟 DOM 元素
// refs {属性: 属性值}
// refs {ref 的值: 对应的 DOM 元素对象}
// refs {"left": <input>元素对象}
class MyComponent extends ReactComponent {
hint = ()=>{
console.log(this.refs.left.value);
} handleBlur = (event)=>{
// console.log(this.refs.right.value);
console.log(event.target.value);
} render(){
return ({
<div>
<input type="text" ref="left"/>
<button onClick={this.hint}></button>
<input type="text" ref="right" onBlur={this.handleBlur} />
</div>
})
}
} ReactDOM.render(<MyComponent/>, document.getElementById("oouter"))- 外部 向 组件对象 传入 props 的两种方式
- 传不确定的 数据
ReactDOM.render(<Person name={sun.name} age={sun.age} sex={sun.sex}/>, document.getElementById("outer"));
- 传不确定的 虚拟 DOM
传一个 虚拟 DOM 标签,组件.props.children
传多个 虚拟 DOM 标签,组件.props.children[{...},{...}...]
- 相关概念:
程序: 是对现实世界的模拟
- jsx 需要注意的地方:
class 必须用 className 代替
style 的属性值必须 {{"color":"red", "font-size": "16px"}}
- 组件的事件处理方式
1. 箭头函数的方式

2. 初始化执行 constructor() 时,bind 绑定 this 从而产生一个新的函数,指向组件对象

- 出现警告:
You provided a `value` prop to a form field without an `onChange` handler. This will render a read-only field. If the field should be mutable use `defaultValue`. Otherwise, set either `onChange` or `readOnly`.
解决:
使用 defaultValue 代替 value

- 实时显示用户输入数据

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Hello React</title> <link rel="stylesheet" type="text/css" href="./css/index.css" />
</head> <body>
<div id="outer"></div> <!-- javascript 代码 -->
<script src="https://cdn.bootcss.com/react/16.7.0/umd/react.development.js"></script>
<script src="https://cdn.bootcss.com/react-dom/16.7.0/umd/react-dom.development.js"></script>
<script src="https://cdn.bootcss.com/babel-standalone/6.26.0/babel.js"></script>
<script type="text/babel">
class ButtonText extends React.Component { // 组件类
hint = ()=>{
alert("left : "+this.refs.left.value)
}
centerInfo = (event)=>{
this.refs.tips.innerHTML = event.target.value
}
handleBlur = (event)=>{
console.log("right : "+event.target.value)
}
render(){
return (
<div>
<div>
<label>
<input type="text" ref="left" defaultValue="Come on!"/>
</label>
<label>
<input type="text" ref="center" onKeyUp={this.centerInfo}/>
</label>
<label>
<input type="text" ref="right" onBlur={this.handleBlur}/>
</label>
</div>
<button onClick={this.hint}>Tips</button>
<p ref="tips">Hello there.</p>
</div>
)
}
} ReactDOM.render(<ButtonText/>, document.getElementById("outer"));
</script>
</body>
</html>
问题: 在 create-react-app 之后的项目,进行 npm run build 时,发现是 用了 "/" 绝对路径,以致于找不到路径
解决: 找到 node_modules/react-scripts/config/paths.js 第 45 行修改 "/" 为 "./"

个人 './' 与 '/' 愚见,觉得 './' 更好,为什么官方设计是 /这样的绝对路径呢?
React 面向组件化编程 - 封装了webpack - npm run build 产生的包的 /static 引用路径问题的更多相关文章
- 移动web端的react.js组件化方案
背景: 随着互联网世界的兴起,web前端开发的方式越来越多,出现了很多种场景开发的前端架构体系,也对前端的要求日益增高,早已经不是靠一个JQuery.js来做前端页面的时代了,而今移动端变化最大,近 ...
- vue组件化编程应用
写几个小案例来理解vue的组件化编程思想,下面是一个demo. 效果图示: 功能: Add组件用于添加用户评论,提交后右边评论回复会立马显示数据.Item组件点击删除可以删除当前用户评论.当List组 ...
- 初探CORBA组件化编程
1.掌握组件化开发的概念,了解CORBA模型及ORB机制:2.掌握CORBA组件编程方法.二.实验内容(一).步骤1.配制环境JDK环境.2.编写编译IDL接口.3.编写编译服务端程序.4.编写编译客 ...
- vue组件化编程应用2
写几个小案例来理解vue的组件化编程思想,下面是一个demo. 效果图示: 需求: header部输入任务,进行添加,在list中显示; list中每个item项,鼠标移入时,背景变灰并显示delet ...
- React中使用create-react-app创建项目,运行npm run eject建立灰度报错
我在运行npm run eject建立测试环境和正式环境时候报错 这里的问题是是脚手架添加.gitgnore文件,但是却没有本地仓库,按照以下顺序就可以正常使用 git add . git commi ...
- React项目配置npm run build命令分环境打包
使用create-react-app脚手架创建的项目默认隐藏了webpack等配置文件信息,使用npm run eject命令暴露这些隐藏的配置文件信息 项目默认有两个环境:开发环境(npm star ...
- 从零搭建react+ts组件库(封装antd)
为什么会有这样一篇文章?因为网上的教程/示例只说了怎么做,没有系统详细的介绍引入这些依赖.为什么要这样配置,甚至有些文章还是错的!迫于技术洁癖,我希望更多的开发小伙伴能够真正的理解一个项目搭建各个方面 ...
- React: 研究React的组件化
一.简介大概 在以往的Web开发中,会把web页面所有的复杂控件作为一个单一的整体进行开发,由于控件之间需要进行通信,因此不同的组件之间的耦合度会很多,由于开发一个控件的时候要考虑到控件与控件之间的联 ...
- React的组件化
所谓组件,即封装起来的具有独立功能的UI部件.React推荐以组件的方式去重新思考UI构成,将UI上每一个功能相对独立的模块定义成组件,然后将小的组件通过组合或者嵌套的方式构成大的组件,最终完成整体U ...
随机推荐
- [物理学与PDEs]第5章习题3 第二 Piola 应力张量的对称性
试证明: 在物质描述下, 动量矩守恒定律等价于第二 Piola 应力张量的对称性. 证明: 由 $$\beex \bea \int_{G_t}\rho\sex{{\bf y}\times\cfrac{ ...
- 7、Servlet会话跟踪
一.会话跟踪: 不管操作多少功能,都是与当前登录用户相关的信息,当前的登录用户始终没有改变,也就是用户名和密码都没有丢失.但HTTP协议是一个无状态的协议,当一个客户向服务器发出请求(request) ...
- Spring系列(零) Spring Framework 文档中文翻译
Spring 框架文档(核心篇1和2) Version 5.1.3.RELEASE 最新的, 更新的笔记, 支持的版本和其他主题,独立的发布版本等, 是在Github Wiki 项目维护的. 总览 历 ...
- JavaWeb - apache和tomcat是如何配合工作的
ref: https://jingyan.baidu.com/article/47a29f246f354ec0142399dc.html 网上有很多的介绍apache和tomcat的区别,但大部分都是 ...
- 抓包工具tcpdump用法说明
tcpdump采用命令行方式对接口的数据包进行筛选抓取,其丰富特性表现在灵活的表达式上. 不带任何选项的tcpdump,默认会抓取第一个网络接口,且只有将tcpdump进程终止才会停止抓包. 例如: ...
- PGCD2 - Primes in GCD Table (Hard)
这题肝了三四天,其他啥也没做... 传送门 然后...双倍经验 简单版 不知道为什么会脑抽去帮 LZ_101 大佬验题... 题目和被 A 穿的 PGCD 一样,数据范围变成大概 2e11 ... 于 ...
- 【原创】Java基础之Session机制
Session机制 JSESSIONID是Session的标识,当客户端请求服务器端的时候,服务器端会检查是否已经给这个客户端创建过Session,也就是看客户端的请求中的header是否有Cooki ...
- noj算法 8皇后打印 回溯法
描述: 输出8皇后问题所有结果. 输入: 没有输入. 输出: 每个结果第一行是No n:的形式,n表示输出的是第几个结果:下面8行,每行8个字符,‘A’表示皇后,‘.’表示空格.不同的结果中,先输出第 ...
- 【异常处理】Java异常如何做异常处理
类似SpringMVC项目的异常处理可以这样做: 整个项目创建全局的: 1.一个自定义异常如OneException和错误码,统一封装所有异常. 2.一个返回实体类ResponseEntity,包含返 ...
- 九.LNMP网站架构实践部署
期中集群架构-第九章-期中架构LNMP章节====================================================================== 01. LNMP ...