首先如果是新项目 最好使用
react脚手架 create-react-app 简单方便干净。
该文章地址:https://blog.csdn.net/qtfying/article/details/78665664
<script src="https://cdn.bootcss.com/react/15.4.2/react.min.js">script>
<script src="https://cdn.bootcss.com/react/15.4.2/react-dom.min.js">script>
<script src="https://cdn.bootcss.com/babel-standalone/6.22.1/babel.min.js">script>
先安装npm install –save react react-dom
import React from 'react'
import ReactDOM from 'react-dom'
import React from 'react'
import ReactDOM from 'react-dom'
//react渲染方法
ReactDOM.render(
//jsx写法的html元素
Hello, world!
,
//渲染目标元素
document.getElementById('area')
)
创建一个网页元素
//创建一个元素element
let element = Hello,element!
//element元素可以在render()直接中渲染
ReactDOM.render(
element,
document.getElementById('root')
);
//element元素可以在组件中调用
class Hello extends React.Component {
render(){
return (
{listItems}
);
}
}
function Hello(props) {
return Hello, {props.name}
;
}
//创建组件需要创建一个类,类名必须首字母大写,必须继承React.Component并实现render()方法
class Hello extends React.Component {
render() {
return Hello, world!
//这里可以直接返回元素element
//return element
}
}
//将组件类名按html形式写在render方法中即可在页面中看到
ReactDOM.render( , document.getElementById('root'))
//组件A
class HelloA extends React.Component {
render() {
return this is A
}
}
//组件B调用组件A
class HelloB extends React.Component {
render() {
return (
<div>
this is B
//此处调用组件A
div>
)
}
}
const element = ;
父组件通过属性的方式传值给子组件
class HelloA extends React.Component {
render() {
return (
//此时组件HelloA 获得attr的值
'fuck'/>
)
}
}
子组件获取值
class HelloA extends React.Component {
render() {
//得到父组件传来的attr值
return this is A {this.props.attr}
}
}
引入PropType库,验证值,避免错误。
import PropTypes from 'prop-types'
MyComponent.propTypes = {
// 你可以将属性声明为以下 JS 原生类型
optionalArray: PropTypes.array,
optionalBool: PropTypes.bool,
optionalFunc: PropTypes.func,
optionalNumber: PropTypes.number,
optionalObject: PropTypes.object,
optionalString: PropTypes.string,
optionalSymbol: PropTypes.symbol,
}
//详情:[https://doc.react-china.org/docs/typechecking-with-
在组件中使用
//新建组件类
class Test extends Component {
//验证属性'name'为字符串,并且不为空
static propTypes = {
name: PropTypes.string.isRequired
}
//渲染
render() {
return (
<div className='aaa'>
'tes'>{this.props.name}
div>
)
}
}
1,状态state与生命周期只能应用于用类创建的组件上。不能应用与方法创建的组件上
2,状态state的初始化需要用es6类的构造函数。
class NewComponent extends React.Component {
//constructor是es6类的构造方法。props父级调用该组件时传递的属性数据
constructor(props) {
//super()方法是子类继承父类必要条件
super(props);
//将date赋予state this.state只能在constructor初始化
this.state = {date: new Date()};
}
//自定义方法
change() {
//该方法用于更新state状态,只有通过该方法,才会重新渲染
this.setState({
date: new Date()
});
}
//渲染
render() {
return (
Hello, world!{this.state.date}
);
}
//钩子函数 当虚拟dom挂在到网页dom上时立即执行
componentDidMount() {
this.timerID = setInterval(
() => this.tick(),
1000
);
}
//钩子函数 当前dom即将从网页dom卸载时执行
componentWillUnmount() {
clearInterval(this.timerID);
}
}
在react+jsx中 事件名用驼峰写法。并且方法用中括号表示
避免被短时间内触发太多次事件的方法控制调用
<button onclick='someFun()' />
<button onClick={someFun} />
事件方法默认无法被绑定到this上,以下几种方法可以解决
1,在组件类的构造函数中绑定
//在构造函数中绑定
constructor(props) {
super(props)
this.clickFunc = this.clickFunc.bind(this)
console.dir(this)
}
//只有绑定才能获取到this
clickFunc(){
console.dir(this)
}
2,在调用时使用回调
3,将事件方法使用箭头函数写法(需要属性初始化器语法开启)
clickFunc=(e)=>{
//事件可以通过e获取参数
console.info(e.target.value)
console.dir(this)
}
//首先创建方法接受参数
handleClick(index, e) {
console.info(index)
// e.preventDefault()]
}
render() {
//使用箭头函数传值。如果使用普通写法,函数会立即执行。
元素方式
let list=[3, 1, 2, 44]
let ListItem=list.map(
//key是唯一标示,x是
(number, index) => {number}
)
jsx嵌入方式
<ul>
{list.map((number) =>
<ListItem key={number.toString()}
value={number} />
)}
ul>
所谓的受控组件,就是react实现表单的双向绑定,只不过它实现的比较复杂。。。。。
class NameForm extends React.Component {
constructor(props) {
super(props);
//初始化状态
this.state = {value: ''};
//绑定事件
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
//值变动事件
handleChange(event) {
this.setState({value: event.target.value});
}
//提交事件
handleSubmit(event) {
alert('A name was submitted: ' + this.state.value);
event.preventDefault();
}
render() {
return (
);
}
}
a组件调用b组件就是继承
class A extends React.Component {
render(){
return <div><div>
}
}
class B extends React.Component {
render(){
return
}
}
那么如果这时组件B需要将元素嵌入到组件A中呢,这时就需要props.children 相当于(VUEJS中到继承)
class A extends React.Component {
render(){
return <div>
//从外部内嵌到元素位置
{props.children}
<div>
}
}
class B extends React.Component {
render(){
return
//在此处内嵌
fuck u
}
}
跨组件调用状态时,父组件通过属性传递到方式 将state与setSate传递给 子组件到props中。子组件发生变化立即更新props传过来到state,达成了状态提升与同步。
class Calculator extends React.Component {
constructor(props) {
super(props);
this.handleCelsiusChange = this.handleCelsiusChange.bind(this);
this.handleFahrenheitChange = this.handleFahrenheitChange.bind(this);
this.state = {temperature: '', scale: 'c'};
}
handleCelsiusChange(temperature) {
this.setState({scale: 'c', temperature});
}
handleFahrenheitChange(temperature) {
this.setState({scale: 'f', temperature});
}
render() {
const scale = this.state.scale;
const temperature = this.state.temperature;
const celsius = scale === 'f' ? tryConvert(temperature, toCelsius) : temperature;
const fahrenheit = scale === 'c' ? tryConvert(temperature, toFahrenheit) : temperature;
return (
<div>
"c"
//子组件到值来自父组件传递
temperature={celsius}
//子组件发生变化更新父组件到 setState控制方法
onTemperatureChange={this.handleCelsiusChange} />
"f"
temperature={fahrenheit}
onTemperatureChange={this.handleFahrenheitChange} />
div>
);
}
}
vue中有相同到东西。但用着方便多类。在react中它只能对class声明对对象使用。
class CustomTextInput extends React.Component {
constructor(props) {
super(props);
// 创建 ref 存储 textInput DOM 元素
this.textInput = React.createRef();
this.focusTextInput = this.focusTextInput.bind(this);
}
focusTextInput() {
// 直接使用原生 API 使 text 输入框获得焦点
// 注意:通过 "current" 取得 DOM 节点
this.textInput.current.focus();
}
render() {
// 告诉 React 我们想把 ref 关联到构造器里创建的 `textInput` 上
return (
<div>
"text"
ref={this.textInput}} />
"button"
value="Focus the text input"
onClick={this.focusTextInput}
/>
div>
);
}
}
当组件a包含组件b,组件b又包含组件c时,如果从a向c传值,就要先传到b,再从b传到c。而使用context就可以直接一步从a传到c
(不要仅仅为了避免在几个层级下的组件传递 props 而使用 context,它是被用于在多个层级的多个组件需要访问相同数据的情景。)
// 创建一个 theme Context, 默认 theme 的值为 light
const ThemeContext = React.createContext('light');
function ThemedButton(props) {
// ThemedButton 组件从 context 接收 theme
return (
{theme => }
);
}
// 中间组件
function Toolbar(props) {
return (
);
}
class App extends React.Component {
render() {
return (
"dark">
);
}
}
有些时候你要返回一个多元素集合,但react只允许你返回一个包含子标签的单个元素,有时我们并不希望这个外部包裹元素被渲染出来,这时可以使用空标签
class Columns extends React.Component {
render() {
return (
<>
Hello
World
>
);
}
}
需要key的时候使用React.Fragment
class Columns extends React.Component {
render() {
return (
Hello
World
);
}
}
render() {
//将this.props.children渲染到制定到domNode上
return ReactDOM.createPortal(
this.props.child欧ren,
domNode,
);
}
前端路由是单页应用到重要条件。根据不同的访问地址来调取不同到组件显示,而不必刷新这个页面。
react-router中文文档
react-router-dom4简约教程
//安装路由
npm install --save react-router-dom
//引入模块
import {
//Router就是个容器。触发route功能都需要在Route标签中。而且只能有一个子标签。
//模仿正常都地址
BrowserRouter,
//地址中有#符号
HashRouter,
//受link控制的 装载组件的容器
Route,
//普通的跳转工具
Link,
//API比较多的跳转工具
NavLink
} from 'react-router-dom'
两个组件
class About extends React.Component {
render() {
return (
<div> about div>
)
}
}
class Contact extends React.Component {
render() {
return (
<div> contack div>
)
}
}
主组件
export default class IndexPage extends Component {
render() {
return (
//路由容器,basname设置基础path
'/home'>
//只能有一个子
<div>
//组件容器。path设置匹配地址,component设置匹配组件。
'/about' component={About} />
'/contact' component={Contact} />
//链接按钮。相当于a标签
'about'>about
'contact'>contact
div>
)
}
}
可以使用自己喜欢的 AJAX 库,如jQuery AJAX 和浏览器内置的 window.fetch。 值得一提的是Axios,目前被vue官方宣传使用,傻瓜操作,完美的跨域解决方案,值得拥有。
数据请求应该在componentDidMount 生命周期方法内发送。这样你才能够在请求的数据到达时使用 setState 更新你的组件。应该在componentWillUnmount生命周期内取消请求
window.fetch的方法贴
fetch('sdf.json地址', {
// 是否允许跨域带cockie
credentials: 'include',
//请求头
headers: {
'Accept': 'application/json'
},
//方法
method: 'get'
}).then(res => res).then(
//获取结果
(result) => {
this.setState({
list: result.list.id
})
},
//捕获错误
(error) => {
this.setState({
error
})
}
)
$.ajax({
url:'http://www.bai.com',
type:"DELETE",
data:{
id:1//假设需要删除id=1的数据
},
dataType:'json',
success:function(e){
console.log(e)
}
})
3.重点推荐axios
npm地址含教程
//假数据,可以拦截请求,用于前端测试,后面有介绍
Mock.mock(
/\.json/,
'get',
// 属性 list 的值是一个数组,其中含有 1 到 10 个元素
{
'age|20-30':25
}
)
//发起请求
Axios({
//方法,restfull
method: 'get',
//地址
url: 'asdf.json',
//返回格式
responseType: 'json'
}).then(function(response) {
//结果
console.dir(response.data)
})
axios取消请求的方法
示例的 API 返回的 JSON 对象使用mock生成,mock可以拦截ajax请求,返回加数据,便于前端调试。
git地址,里面有配置教程
npm i mockjs
配置
var Mock = require('mockjs')
var data = Mock.mock(
//期望被拦截的地址。当你的react请求这个地址时就会返回我们的加数据
/\.json/,
'get',
// 属性 list 的值是一个数组,其中含有 1 到 10 个元素
{
'age|20-30':25
}
)
// 输出结果
console.log(JSON.stringify(data, null, 4))
const Random = Mock.Random
console.dir(Random.csentence(5, 30))
模拟resful处理的帖子
/*模拟删除数据的方式*/
var arr=[
{name:'fei',age:20,id:1},
{name:'liang',age:30,id:2},
{name:'jun',age:40,id:3},
{name:'ming',age:50,id:4}
]
Mock.mock('http://www.bai.com','delete',function(options){
var id = parseInt(options.body.split("=")[1])//获取删除的id
var index;
for(var i in arr){
if(arr[i].id===id){//在数组arr里找到这个id
index=i
break;
}
}
arr.splice(index,1)//把这个id对应的对象从数组里删除
return arr;//返回这个数组,也就是返回处理后的假数据
})
如果less中 不能使用函数,那可能是style-css 和 less-loader顺序问题。
在less文件中无法使用css3的@keyfreames动画语法。这时可以在文件中定义一个类的keyfreames语句,然后在页面中使用improt style from 'xxx.less' 并在模版中使用用这种龌龊的方法调用style
由于数据内容都是前端渲染出来的,所以不利于搜索引擎seo。这时需要server render来处理就好了。