React笔记
1.安装React
== React 需要知道 jsx babel 然后有es6、html、javascript ==
1.直接引入js
直接上代码和测试
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>MyH2HTML</title>
<script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>
<script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
</head>
<body>
<div id="example">
<script type="text/babel">
ReactDOM.render(
<h1> hello React</h1>,
document.getElementById('example')
)
</script>
</div>
</body>
</html>
效果
2.使用脚手架create-react-app 来创建项目(推荐)
安装步骤
- 确保安装了nodejs、npm(如果没有,请自行度娘,安装)
- 为了确保下载速度,安装cnpm并使用阿里镜像下载
#安装 cnpm
npm install -g cnpm --registy=https://registry.npmmirror.com
# 安装create-react-app
cnpm install -g create-react-app
效果图
-
推荐使用vscode 来开发项目
-
创建项目
- 切换到项目目录
- 使用命令
create-react-app myfirstApp
如图显示完成创建:
-
测试Hello World
- 启动项目 切换到刚才创建的项目目录下,执行
npm start
- 端口默认3000,浏览器中输入地址:
http://localhost:3000
,可以打开表示启动成功 - 根据首页提示,修改首页App.js 将Hello World 放进去!
// 修改后如下 import logo from './logo.svg'; import './App.css'; function App() { return ( <div className="App"> <header className="App-header"> <img src={logo} className="App-logo" alt="logo" /> <h1>Hello world</h1> </header> </div> ); } export default App;
- 启动项目 切换到刚才创建的项目目录下,执行
截图看效果
2.直接引入js中React语法及用法
2.1 渲染时传参
2.1.1 直接渲染
<head>
<!-- 引入js -->
<script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>
<script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
</head>
<body>
<div id="div1"></div>
<script>
function time1(){
let ele=(
<div>
<h1>测试时间</h1>
<h2>nowTime=>{new Date().toLocalTimeString()}</h2>
</div>
)
ReactDOM.render(
el2,
document.getElementById('div1')
)
}
// 执行定时方法,来刷新渲染
setInternal(()=>{time1()},1)
</script>
</body>
2.1.2 传参
111
<html>
<head>
<!-- 引入js -->
<script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>
<script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
</head>
<body>
<div id="div1"></div>
<script>
// 这里的名称 首字母必须大写,应为下面要用到 此方法的标签,这里的props ,名称任意(他这里类似 function内部的this 差不多的意思,可暂时这么理解)
function Ele1(props){
// 打印查看值
console(props) // new Date() 否的对象
console(this) // undified
return (
<div>
<h1>测试时间</h1>
// 这里的date2 随意命名,与下面使用时对应即可
<h2>nowTime=>{props.date2.toLocalTimeString()}</h2>
</div>
)
}
function renderEle(){
ReactDOM.render(
// 使用Ele1中定义的 字段来赋值传参
<Ele1 date2={new Date()} />,
document.getElementById('div1')
)
}
// 执行定时方法,来刷新渲染
setInterval(()=>{renderEle()},1)
</script>
</body>
</html
2.1.3 使用ES6中的类
<html>
<head>
<!-- 引入js -->
<script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>
<script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
</head>
<body>
<div id="div3"></div>
<script>
class Clock3 extends React.Component {
render(){
return (
<h1>测试时间</h1>
// 这里必须是this.props 因为是在类的内部了所以要使用this; 这里的date3 随意命名,与下面使用时对应即可
<h2>nowTime=>{this.props.date3.toLocalTimeString()}</h2>
)
}
}
// 执行定时方法,来刷新渲染
function render3(){
ReactDOM.render(
<Clock3 date3={new Date()} />,
document.getElelmentById('div3')
)
}
setInternal(()=>{render3()},1)
</script>
</body>
</html>
2.1.4综合范例
<html>
<head>
<!-- 引入js -->
<script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>
<script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
</head>
<body>
<div id="div4"></div>
<script type="text/babel">
let mystyle={color:'red',textAlign:'center'}
class MyName extends React.Component {
render(){
return <h2 style={mystyle}> 名称:{this.props.nm1} </h2>;
}
}
class MyUrl extends React.Component {
render(){
return <h2> 地址:<href>{this.props.u1}</href></h2>
}
}
class MyNick extends React.Component {
render(){
return <h2> 昵称:{this.props.nk1}</h2>
}
}
function MyApp(props){
return (
<div>
<MyName nm1={props.myProps.name} />
<MyUrl u1={props.myProps.url} />
<MyNick nk1={props.myProps.nick} />
</div>
)
}
function render4(){
ReactDOM.render(
<MyApp myProps={{name:"Miller",url:"www.dongmanqu.cn",nick:"请叫我小可!"}} />,
document.getElementById('div4')
)
}
render4();
</script>
</body>
</html>
2.2 React JSX
React 使用 JSX 来替代常规的 JavaScript 是一个看起来很像 XML 的 JavaScript 语法扩展
- JSX 执行更快,因为它在编译为 JavaScript 代码后进行了优化
- 它是类型安全的,在编译过程中就能发现错误
- 使用 JSX 编写模板更加简单快速
简单示例,类似这种
const element = <h1>Hello, world!</h1>
2.2.1 JSX中支持的写法
- 计算表达式 类似 1+1
<div id='d1'></div>
<script type='text/babel'>
let name='展示表达式'
let ele=<div>
<h1>{name}</h1>
<h2>1+1={1+1}</h2>
</div>
ReactDOM.render(
ele,document.getElementById('d1')
)
</script>
- 三目表达式
<div id='d2'></div>
<script type='text/babel'>
let name='三目表达式';
let i=1;
let ele=<div>
<h1>{name}</h1>
<h2>'true? v1 : v2'===>{i==1?'i是1':'i不是1'}</h2>
</div>
ReactDOM.render(
ele,document.getElementById('d2')
)
</script>
- jsx注释
<div id='d3'></div>
<script type='text/babel'>
ReactDOM.render(
<div>
<h1>测试注释</h1>
{/*注释也必须使用{} 括起来 */}
</div>
,document.getElementById('d3')
)
</script>
- 样式、数组
<div id='d3'></div>
<script type='text/babel'>
let mystyle={
color:'red',
fontSize:'xxx-large'
}
// 这里要给 h1、h2 标签添加key 属性,
// 添加key可以保证dom结构的完整性,而不会根据react自己对dom标记的key进行重新分配 react每次决定重新渲染的时候,几乎完全是根据data-reactid来决定的,最重要的是这个机制。(react的key是react的dom-diff算法的关键,对于dom的操作是根据生成的data-reactid进行绑定的)
let arr=[
<h1 key='arr-1'>测试数组--1</h1>,
<h2 key='arr-2'>测试数组--2</h2>
]
ReactDOM.render(
<div>
<h1 style={mystyle}>测试注释</h1>
{/*注释也必须使用{} 括起来 */}
{arr}
</div>
,
document.getElementById('d3')
)
</script>
2.3 React组件
组件:将逻辑封装到一个方法中或者ES6中的类中;前面已经用过例子了,查看 2.1.4综合范例
这里将上面的综合范例,使用ES6类的方式在写 一下
特别注意,无论是ES6类 还是 function封装 名称首字母必须大写
2.3.1 组件使用案例
<html>
<head>
<title>this is title</title>
<!-- 引入reactjs 这里不写了 -->
</head>
<body>
<div id='h1'></div>
<script type='text/babel'>
// <!-- function 封装 hello -->
function Hello(props){
return <h1> Hello {props.msg} !</h1>
}
let ele=<Hello msg='Miller' />
ReactDOM.render(ele,document.getElementById('h1'))
</script>
<!-- 这里是使用ES6类的形式 封装的 -->
<div id='h2'></div>
<script type='text/babel'>
const myStyle1={
color:'red',
fontSize:'xx-large',
textAlign:'center'
}
const myStyle2={
color:'blue',
fontSize:'x-large',
}
class Name extends React.Component {
render(){
return <h2 style={myStyle1}>{this.props.nm}</h2>
}
}
class Url extends React.Component {
render(){
return <h2 style={myStyle2}>{this.props.u}</h2>
}
}
class Nick extends React.Component {
render(){
return <h2 style={{fontSize:'large',color:'gray'}}>{this.props.nk}</h2>
}
}
class App extends React.Component {
render(){
return
<div>
<Name nm={this.props.appNm} />
<Url u={this.props.appUrl}/>
<Nick nk={this.props.appNk}/>
</div>
}
}
ReactDOM.render(
<App appNm='Miller' appUrl='http://www.dongmanqu.cn' appNk='他们都叫我小可' />
,
document.getElementById('h2')
)
</script>
<!-- 这里是使用function 封装的 -->
<div id="h3"></div>
<script type="text/babel">
function Name2(props){
return <h2> 名称:{props.nm} </h2>
}
function Url2(props){
return <h2>地址:<a href={props.u}>{props.u}</a></h2>
}
function Nick2(props){
return <h2>昵称:{props.nk}</h2>
}
function App2(props){
return <div>
<Name2 nm={props.appNm} />
<Url2 u={props.appUrl} />
<Nick2 nk={props.appNk} />
</div>
}
ReactDOM.render(
<App2 appNm={'周杰伦'} appUrl={'https://www.baidu.com'} appNk={'七里香'} />,document.getElementById('h3')
)
</script>
</body>
<html>
2.3.2 组件props与child用法
-
props 可以传参,使用时在标签中类似
<T1 name={} />
这种传参 -
child 在标签内部
<T1> children</T1>
使用案例 循环10 以内的数字来展示自然
<html>
<head>
。。。各种引入
</head>
<body>
<div id='a1'></div>
# T1使用 children 的写法
<script type='text/babel'>
function Repeat(props) {
let items=new Array();
for(let i=0;i<props.nums;i++){
items.push(props.children(i))
}
return (<div> </div>)
}
function P1(props) {
return <p>this is {props.cIndex} in the items</p>
}
function T1() {
return (
<Repeat nums={3}>
{
(i)=>{
return <P1 key={i} cIndex={i} />
}
}
</Repeat>
)
}
</script>
<div id='a1'></div>
# 使用 props.name 传参的写法
<script type='text/babel'>
function Repeat(props) {
let items=new Array();
for(let i=0;i<props.nums;i++){
items.push(props.ele(i))
}
return (<div> </div>)
}
function P1(props) {
return <p>this is {props.cIndex} in the items</p>
}
function T1() {
return (
<Repeat nums={2} ele={(i)=>{return <P1 key={i} cIndex={i} />}} />
)
}
</script>
</body>
</html>
2.4 React state使用
React 把组件看成是一个状态机,只需要更新state,然后React根据新的state来重新渲染用户界面
<html>
<head>...</head>
<body>
<div id='d1'></div>
<div id='d2'></div>
<script>
var dateStyle={color:'red',fontSize:'xxx-large',marginLeft:'2em'}
// 定义时间格式化组件
function FormatMyDate(props) {
return <p style={dateStyle}>{props.date1.toLocalTimeString()}</p>
}
// 定义时间类组件
class Clock extends React.Component {
// 定义构造方法,并指定传参
constructor(props){
super(props)
this.state={myDate:new Date()}
}
// 定义更新方法
tick() {
this.state={myDate:new Date()}
}
// 当Clock组件渲染到DOM时,挂载定时器
componentDidMount() {
this.myTimer=setInterval(()=>{this.tick();},1000)
}
// Clock组件移出时 卸载 定时器
componentWillUnMount() {
clearInterval(this.myTimer)
}
// 定义返回值
render() {
return (
<div>
<h1>北京时间</h1>
<FormatMyDate date1={this.state.myDate} />
</div>
)
}
}
// 渲染用户界面
ReactDOM.render(<Clock />,document.getElementById('d1'))
// 组件可复用
ReactDOM.render(
<div>
<Clock />
<Clock />
<Clock />
</div>,
document.getElementById('d2')
)
</script>
</body>
</html>
2.5 React Props
state 和 props 主要的区别在于 props 是不可变的,而 state 可以根据与用户交互来改变。
所以一般是这种用法
state
用来更新数据props
用来做参数做传递
做一个例子,父子组件,数据相互同步
<html>
<head>.....</head>
<body>
<div id='d1'></div>
<script type='text/babel'>
class P1 extends React.Component {
constructor() {
super()
this.state={fName:'显示名称'}
}
// 点击按钮 先更新父组件名称,在同步到子组件名称
pClick() {
this.setState={fName:'名称更改了!!!'}
}
// 如果子组件,名称变更了,同步到父组件中
childChangeFun(e) {
this.setState={fName:{e.target.value}}
}
render() {
return (
<div>
<h1>测试父子组件 数据互相同步</h1>
<p>父组件:{this.state.fName}</p>
<input type='button' value={'点击更改名称'} onClick={()=this.pClick()} />
<C1 childFName={} childFun={(e)=>this.childChangeFun(e)} />
</div>
)
}
class C1 extends React.Component {
render() {
return (
<p>子组件:
<input type='text' value={this.props.childFName} onChange={this.props.childFun} />
</p>
)
}
}
ReactDOM.render(
<P1 />,document.getElementById('d1')
)
}
</script>
</body>
</html>
2.6 条件渲染
类似Javascript 中使用if 条件或者其他状态值来返回不同的组件渲染
2.6.1 使用if、三目运算符
<html>
<head>
# ... js 引入等
</head>
<body>
<div id='d1'></div>
<script type='text/babel'>
class HomePage extends React.Component {
constructor() {
super()
this.state={showWord:'请先登录',isLogin:false}
}
logout() {
this.setState({showWord:'请先登录',isLogin:false})
}
login() {
this.setState({showWord:'欢迎您,Miller先生',isLogin:true})
}
btnClick() {
let loginFlag=this.state.isLogin;
this.setState({showWord:loginFlag?'请登录':'欢迎您,Miller先生',isLogin:!loginFlag})
}
render() {
let btn=null;
if(this.state.isLogin){
btn=<input type='button' value='退出' onClick={()=>this.logout()} />
}else{
btn=<input type='button' value='登录' onClick={()=>this.login()} />
}
<div>
<h1>{this.state.showWord}</h1>
{btn}
<p>使用三目运算符:<input type='button' value={this.state.isLogin?'请退出':'请登录'} onClick={()=>this.btnClick()} /></p>
</div>
}
}
ReactDOM.render(
<HomePage />
,document.getElementById('d1')
)
</script>
</body>
</html>
2.6.2 与运算符 && 、阻止组件渲染 (null、或者空的一个元素)
- 与运算符 &&
<html>
<head>
# ... js 引入等
</head>
<body>
<div id='t1'></div>
<script type='text/babel'>
class P1 extends React.Component {
constructor(props) {
super(props)
}
render() {
let s2={
color:'red',
fontSize:'xx-large',
margin:'0em 0.2em'
}
return (
<div>
<h1>欢迎,miller</h1>
{
this.props.msg.length > 0 &&
<h2>还有<span style={s2}>{this.props.msg.length}</span>条未读消息</h2>
}
</div>
)
}
}
ReactDOM.render(
<P1 />
,document.getElementById('t1')
)
</script>
<div id='t2'></div>
<script type='text/babel'>
</script>
</body>
</html>
- 阻止组件渲染 (null、或者空的一个元素)
<html>
<head>
# ... js 引入等
</head>
<body>
</body>
<div id='t1'></div>
<script type='text/babel'>
class P1 extends React.Component {
constructor() {
super()
this.state={showFlag:true}
}
click() {
// 第一种写法
// this.setState({showFlag:!this.state.showFlag})
// 第二种 接近于 let preState=this.state
this.setState(prevState=>({showFlag:!prevState.showFlag}))
}
render() {
return (
<div>
<h1> 阻止组件渲染 </h1>
<WarnBar showTag={this.state.showFlag} />
<p><input type='button' value={this.state.showFlag?'隐藏':'显示'} onClick={()=>this.click()} /></p>
</div>
)
}
}
function WarnBar(props) {
let ele=null
let warnStyle={
backgroudColor:'red',
color:'white',
fontSize:'xxx-large',
padding:'1em',
textAlign:'center'
}
if(props.showTag){
<p style={warnStyle}> 警告</p>
}
return ele;
}
ReactDOM.render(
<P1 />,document.getElementById('t1')
)
</script>
</html>
2.7 主要组件API
2.7.1 state
- setState
将原来的值与新的值合并,如state原来的值:{a1:'a','b1':'b'}
;
执行方法setState({a1:'a1'})
执行方法后 state的值为{a1:'a1','b1':'b'}
- replaceState
将原来的值覆盖,如state原来的值:{a1:'a','b1':'b'}
;
执行方法setState({a1:'a1'})
执行方法后 state的值为{a1:'a1'}
2.7.2 props
- setProps
类似 setState - replaceProps
类似 replaceState - forceUpdate
强制重新渲染,如果Prop中值没变,则值更改DOM
2.7.3 获取节点
- findDOMNode
2.7.4 挂载/卸载
- 挂载 componentDidMount
- 卸载 componentWillUnmount
- 判断 isMounted
2.8 生命周期
组件挂在的生命周期一共有以下几个
componentWillMount
这个在18后尽量不要用了,逻辑可以直接用在 didMount中componentDidMount
完成挂载,不支持传参<html> <head></head> <body> <script type='text/babel'> class A4 extends React.Component { componentDidMount() { // 完成加载,且不支持传参,如果传参为:undefined } render(){ return <h1>hello</h1> } } </script> </body> </html>
- componentWillReceiveProps 将接收新的state数据
<html> <head></head> <body> <script type='text/babel'> class A4 extends React.Component { componentWillReceiveProps (newState) { // 将接收新的state数据,支持传参,newState 为更新后的state数据 } render(){ return <h1>hello</h1> } } </script> </body> </html>
- shouldComponentUpdate 是否刷新新的state数据到dom中
<html> <head></head> <body> <script type='text/babel'> class A4 extends React.Component { shouldComponentUpdate (newState) { // 将接收新的state数据,支持传参,newState 为更新后的state数据 return true;// true (默认) 刷新 false 不刷新 } render(){ return <h1>hello</h1> } } </script> </body> </html>
- componentDidMount 是否刷新新的state数据到dom中
<html> <head></head> <body> <script type='text/babel'> class A4 extends React.Component { componentDidMount (preState) { // 支持传参 将接收的state数据为更新前的state数据,支持传参 } render(){ return <h1>hello</h1> } } </script> </body> </html>
- componentWillUnmount 删除dom组件时,卸载此组件
<html> <head></head> <body> <script type='text/babel'> class A4 extends React.Component { componentWillUnmount () { // 不支持传参 删除dom组件时,卸载此组件 } render(){ return <h1>hello</h1> } } </script> </body> </html>
完整案例
<html>
<head></head>
<body>
<script type='text/babel'>
class A4 extends React.Component {
// componentWillMount() {
// console.log('Component WILL MOUNT!')
// }
componentDidMount(newProps) {
console.log('Component DID MOUNT!'+JSON.stringify(newProps))
}
// componentWillReceiveProps(newProps) {
// console.log('Component will receive Props-->'+JSON.stringify(newProps))
// }
shouldComponentUpdate(newState) {
let flag=true;
console.log('是否继续渲染?-->'+flag+";data-->newState"+JSON.stringify(newState))
return flag;
}
// componentWillUpdate() {
// console.log('Component WILL UPDATE!');
// }
componentDidUpdate(prevState) {
console.log('Component did UPDATE!' +JSON.stringify(prevState)+";-->"+JSON.stringify(this.state));
}
componentWillUnmount() {
onsole.log('Component WILL UNMOUNT!')
}
render(){
return <h1>hello</h1>
}
}
</script>
</body>
</html>
2.9 axios (替代ajax)
- 案例1
<!DOCTYPE html>
<html>
<head>
<title>react-html4</title>
<meta charset="utf8">
<script src="https://cdn.staticfile.org/react/18.2.0/umd/react.development.js"></script>
<script src="https://cdn.staticfile.org/react-dom/18.2.0/umd/react-dom.development.js"></script>
<script src="https://cdn.staticfile.org/babel-standalone/7.22.9/babel.min.js"></script>
<script src="https://cdn.staticfile.org/axios/1.4.0/axios.min.js"></script>
</head>
<body>
<div id="u1"></div>
<script type="text/babel">
function fetch(postParams) {
axios.defaults.baseURL='http://127.0.0.1:20621'
axios.get('user/list',{})
.then(
function(result){
console.log('rst')
console.log(result)
return JSON.stringify(result.data)
}
)
.catch(
function(error){
console.log('error')
console.log(error)
}
)
}
function U3(uObj){
return (
<li>
<h3>{"id:"+uObj.data.id+";name:"+uObj.data.name}</h3>
<p>{JSON.stringify(uObj.data)}</p>
</li>
)
}
class U2 extends React.Component {
constructor(props){
super(props)
}
render() {
if(this.props && this.props.uList){
let items=new Array();
for(let i=0;i<this.props.uList.length;i++){
items.push(<U3 key={this.props.uList[i].id} data={this.props.uList[i]} />)
}
return (
<div>
<ul>
{items}
</ul>
</div>
)
}
return null;
}
}
class User extends React.Component {
constructor(props) {
super(props)
this.state={}
this.click=this.click.bind(this)
}
dataChange(e) {
this.setState((prevState)=>{
return {shopCode:e.target.value,id:e.target}
})
}
click() {
let postParam={
"biz": {
"data": {
"shopCode":this.state.shopCode
}
},
"sys": {
"entCode": "1001",
"plat": "",
"token": "",
"userId": 0
}
}
let thisClz=this;
axios.defaults.baseURL='http://127.0.0.1:20621'
//参数1地址,参数2 请求参数 参数3 头部信息
axios.post('user/query',postParam,{
headers:{
"Content-Type":"application/json;charset=utf-8"
}
})
// axios({
// method:"POST",
// url:'user/query',
// headers:{
// "Content-Type":"application/json;charset=utf-8"
// },
// data: postParam
// })
.then(
function(result){
console.log(result)
if(result.data.code=='200'){
thisClz.setState({userInfo:result.data.result})
}else{
alert(result.data.message)
}
},
function(error){
console.log(error)
},
)
.catch(
function(error){
console.log('error')
console.log(error)
}
)
}
render() {
return (
<div>
<p><input type='text' name={'shopCode'} onChange={(e)=>this.dataChange(e)} /></p>
<p><input type='button' value={'获取用户信息'} onClick={this.click} /></p>
<U2 uList={this.state.userInfo} />
</div>
)
}
}
ReactDOM.render(<User />,document.getElementById('u1'))
</script>
</body>
</html>
- 案例2 查询数据填充select 下拉选择后,查询具体信息
<html>
<head>
<meta charset='utf-8' />
<!-- js引入 -->
<body>
<script type='text/babel'>
axios.defaults.baseURL='http://127.0.0.1:20621';
// 统一使用全参数模式 不使用axios.get() 等方法;没用过axios,算是新手入门
// 这里算是初步学习怎么用,详细参考 https://www.axios-http.cn/docs/intro
// get
function req_get(params){
axios({
method:'GET',
url:'user/quer',
header:{}
data:{'id':1805} // 传参
})
.then(
function(resp){
console.log('返回值-》'+JSON.stringfy(resp))
}
)
.catch(
function(error){
console.log('error->'+error)
}
)
}
// post 使用async
async function req_post(params){
let rst=await axios({
method:'POST',
url:'user/query',
headers:{'content-type':'application/json;charset=utf8'},
data:params
})
.then(function(rsp){
consolog.log('返回值'+JSON.stringfy(rsp))
return rsp;
})
.catch(function(err){
console.log(err)
})
console.log('上面执行完成后,才会打印')
return rst;
}
// form 提交
function req_postForm(params){
let paramStr=Object.keys(params).map(k=>`${k}=${encodeURI(params[k])}`).join('&');
return axios({
method:'POST',
url:'user/id',
headers:{'content-type':'x-www-form-urlencoded'},
data:paramStr
})
.then(function(rsp){
console.log('返回值->'+JSON.stringfy(rsp))
return rsp;
})
}
</script>
<div id='d1'>
<script type='text/babel'>
class FromApp extends React.Component {
constructor(){
super()
this.state={shopCode:'100101'}
this.obj={} //
}
sCodeChange(e){
this.setState((preState)=>{
return {shopCode:e.target.value}
})
}
queryBysCode(){
let thisClz=this;
// 这里使用 function关键字 async
let params={'shopCode':this.state.shopCode};
req_post(params).then(function(rsp){
thisClz.setState({selectDataArr:rsp.data})
})
}
selectChange(e) {
Object.assign(this.obj,{selectedValue:e.target.value})
}
queryUserById(){
let thisClz=this;
let param={id:this.obj.selectedValue}
// 使用Promise函数,来实现async功能
new Promise((r,rj)=>{
r(req_postFrom(param))
})
.then(function(rsp){
thisClz.setState((preState)=>{
return {userData:rsp}
})
})
}
render(){
return (
<div>
<input type='text' value={this.state.shopCode} onChange={(e)=>this.sCodeChange(e)} />
<input type ='button' value='查询' onClick={()=>this.queryBysCode()}
<FormSelect formSelected={(e)=>this.selectChange(e)} data={this.state} />
<UserDetailInfo data={this.state.userDetailData} queryUserInfo={()=>{this.queryUserById()}} />
</div>
)
}
}
function FormSelect(props){
let formTitle=null
let optArr=new Array();
if(props && props.data && ){
if(props.data.shopcode){
formTitle=props.shopCode+'下用户'
}
if(props.data.selectDataArr){
for(let i=0;i<props.data.selectDataArr.length;i++){
optArr.push(<SelectOpt key={props.data.selectDataArr[i].id} data={props.data.selectDataArr[i]} />)
}
}
}
return (
<div>
<form>
<label>{formTitle}</label>
<select name ='uId' title='用户列表' onChange={props.formSelected} >
{optArr}
<select>
</form>
</div>
)
}
function SelectOpt(props){
let el=null
if(props && props.data){
el=<option value={props.data.id} > {props.data.name} </option>
}
return el
}
function UserDetailInfo(props){
let el=null;
let ttStyle={
width:'60%',
height:'20em'
}
if(props && props.data){
el=(
<p>
<h2>{'用户【'+props.data.name+'】详细信息'}</h2>
<textarea style={ttStyle} value={JSON.stringfy(props.data)} />
</p>
)
}
return (
<div>
<input type='button' onclick={props.queryUserInfo} value='查看用户详情' />
{el}
</div>
)
}
</script>
</body>
</head>
</html>
2.10 refs使用
React 支持一种非常特殊的属性 Ref ,你可以用来绑定到 render() 输出的任何组件上
<script type='text/babel'>
class TestRef1 extends React.Component {
btnClick() {
this.refs.testRefInput.focus();
let i2=this.testRef2;
i2.current.value='给 iput2 赋值 '
let i3=this.testRef3;
i3.value='给 input3 赋值了'
}
render(){
return (
<div>
<input type='text' ref='testRefInput' >
<br />
<input type='text' ref={this.testRef2} > // 第二种写法
<br />
<input type='text' ref={(c)=>{this.testRef3=c}} > // 第三种写法
<br />
<input type='button' value='点击我获取输入框光标' onClick={()=>{this.btnClick()}}
</div>
)
}
}
ReactDOM.render(<TestRef1 />,document.getElementById('rf1'))
</script>