前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >react基础使用

react基础使用

作者头像
Sarlren
发布2022-10-28 11:27:00
1.2K0
发布2022-10-28 11:27:00
举报
文章被收录于专栏:Sarlren的笔记

1. 不再使用react.createElement

使用jsx创建对象。并最后使用ReactDom.render(param1, param2)去对对象渲染。其中param1为js创建的变量,param2为原生dom方法选中的html元素。

在jsx中的html部分使用js变量等js语法应外加大括号。 render后会接diff.render并非重头对所有元素进行渲染,只会挑出其与之前变化的部分进行重新渲染.


2. map对数组批量操作

类似foreach、map实现对js数组进行批量化操作。给定数组list,使用方法为list.map(item => target),target为目标变量。 在使用map的时候应该加入key,一般是对html元素添加key属性,key属性的内容是特异的。 map不仅自执行循环,同时可以用来做return直接渲染。 map的箭头函数必须要有返回值。


3. 组件写法

代码语言:javascript
复制
class Component extends React.Component {
    render () {
        return (
            <div>component here</div>
        )
    }
}

注意到类名首字母必须大写、必须提供render方法以及必须有返回值。在渲染的时候将原param1改为<Component />这样的方式。事实上<Component />这样的写法在代码中都是对组件的调用,并不局限于渲染函数。 如果在独立js写组件,开头应import React …,在这里要暴露几个组件,写法为export default class YourClassName extends React.Component{}


state和setState注意事项

在组件html代码中可以添加事件。事件内容应为this.functionName,其中functionName为本类下的类方法,注意此处事件内容后不需添加括号,但仍需外侧方括号。在functionName括号中的变量即为当前事件对象。 在组件中的状态初始化可以使用简写,即直接使用

代码语言:javascript
复制
state = {
    var : 0
}

应当注意,为了性能起见,state应当只存放与渲染有关的数据,其余数据如要在多个方法中使用应放到this中. 在类内其他地方调用state中属性应通过this.state.var使用,且state私有。state的修改不能直接通过访问变量直接操作进行修改,需要通过

代码语言:javascript
复制
this.setState({
    var : this.state.var + 1
})

也可以利用扩展运算符新建对象,在新对象中修改并对原来state赋值,这样就能安全地修改state.

诸如此类的操作进行修改。但这样会带来一个问题。比如在button指定了onClick事件,事件函数func内部需要修改state。这个时候应该将事件函数改写成

代码语言:javascript
复制
func **= () =>** {

}

箭头函数。这样可以避免不必要的麻烦。

setState函数是异步更新的,所以不要依赖另一个setstate来写当前的setState.

如果想要setState依赖于前一个state去写的话,写法如下:

代码语言:javascript
复制
this.setState((state, props) => {
    return {
        var : state.var + 1
    }
})

虽然这么写可以让下面读到的state变化,但这仍然是异步的.

setState还有第二个参数.如果写上第二个参数,意为在重新渲染完之后进行的操作.写法例如:

代码语言:javascript
复制
this.setState((state, props) => {}, () => {
    console.log('over rendering')
})

在return某些html对象的时候里面要插入语句,应该写成表达式,即用三元运算符替代if语句。换言之,return中的js只能写表达式。


在js中获取键值对中的值有特别的写法。例如键值对a = [k: ‘1’, m: ‘2’, n: ‘33’],想要获取两个数值只需要写入

代码语言:javascript
复制
const {k, m} = a //此处必须同名,获取之后可以直接使用变量k,m

扩展运算符:对参数对象进行遍历并取出所有可遍历属性,在前面加三个点,类似copy的操作。例如:

代码语言:javascript
复制
let bar = { a: 1, b: 2 };
let baz = { c: 3, ...bar }; // { c: 3, a: 1, b: 2 }

如果在一个数组类型中,前面是扩展运算符,后面的key和前面重叠意为修改前面扩展运算符的键值对.


可控组件

常用于表单处理。用法是写到input框中的onChange属性中的一个函数this.func。在func声明的时候写法会同上面不一样。

代码语言:javascript
复制
// 此处默认state仍同上
func = var2 => {
    this.setState({
        var : var2.target.value // 这样写是为了获取表单的值,且实时获取至类内state中,其中var2是对象,target是固有写法,value是对象属性
    })
}       
// 而且在input标签的value属性要写上value={this.state.var}

html中四种表单分别为input type=”text”、textarea(富文本框)、select(下拉框)、input type=”checkbox”(复选框),前三个的内容属性都为value,第四个是checked。

在多表单处理的时候,通常对不同的表单添加name属性,这样可以只写一个在onChange的函数并设置为多出口。写法为

代码语言:javascript
复制
const name = var2.target.name
this.setState({
    [name] : yourTargetValue // 此处方括号直接字符串转变量
})

组件onClick等事件传参

这里的传参十分反人类。比如某个部件onClick要传参数,按照this.method(num)是不行的。必须写成 onClick = {e => this.method(e, num)},而且在method里面也得把e写上。


4.组件通信

这里仅说明类实现的组件通信。组件通信应该写在渲染部分,具体写在渲染的html对象那个参数里面,如 <component pr='hello' echo='nn' /> 这样就能在class中去调用pr和echo这两个属性。在组件通信中,返回的是一个对象列表,使用关键字为this.props,如要调用具体内容,写为this.props.pr等。props传所有数据都可以,但只可读不可写。 如果类组件中重构过constructor还要使用props,就需要在constructor中的super(props)这样将props传入,否则拿不到,同时constructor的形参也要写props来接收。


如果在调用实例中不写为<component />而写为<component>content</component>,这里的content会成为props的一个元素,即props.children,如果这里的content是个函数,甚至可以props.children()来调用。这里了解即可,一般人不会这么写。 Props可以指定类似函数一样的默认值。当在实例化<component />时不指定props,而在外面加上 component.defaultProps={Var: key} 这样的语句,就默认在props里指定了Var: key这样的默认值。

父传递给子组件

在父组件调用子组件的时候像上面组件通信提到的写法即可传递。在子组件中props即为通信内容。 通信记得传key!且key在子组件props中读不到。还要指定另外的变量才能拿到key里的内容。

父组件调用子组件的信息

分三步完成。即在父组件写入调用函数及对调用信息的处理、写入子组件的对象参数(写入的是那个父组件中调用的函数)、在子组件中处理。例子如下:

代码语言:javascript
复制
class Father extends React.Component {
    getChild = data => {
        // deal with data
    }
    render () {
        return(```<Child getKeyWord={this.getChild} />```)
    }
}

class Child extends React.Component {
    returnProps = () => {
        this.props.getKeyWord('targetData') //注意到此处getKeyWord应和上面调用时的属性一致
    }
    render () {
        return(<button onClick={this.returnProps}></button>)
    }
}

兄弟组件相互通信

这个地方比较繁琐,但很好理解。比如Component1要与Component2通信,获取Component2数据,则要用到公共父类,其中公共父类提供state中的键值对让两者共享,还要提供方法让Component2调用来传Component2的数据。 具体操作为,在Component1中写入state的值,在Component2中调用父类提供方法,按上面说的父组件调用子组件去处理。简言之,Component1要获取Component2的数据,就是Component2先于父类通信传递信息到父类,再交给Component1。代码重复度和上面较高,不再举例。

跨组件通信

这一般是在远房亲戚(嵌套多层)情况下使用。先选定想要相互通信的两个组件。在发送方外部套上<Provider value='yourTargetValue'></Provider>,其中value这个关键字不能变。 但是比较反人类的是,接收方必须要在内部套上<Consumer>{data => <div>{yourDealingData}</div>}</Consumer>,其中最外层首字母大写和形式不能变。内部是一个函数的样子,用来接收数据。

props校验

就像py的assert一样,这被用于类型检查。比如在class App外边渲染的时候回传通信信息,我们想要对回传的信息进行格式校验,就在外侧写入校验字段。例如:

代码语言:javascript
复制
    App.propTypes = {
        yourVarName: PropTypes.array //指定为数组类型
    }
PropTypes的类型常用的有array、bool、func、number、object、string
如果对应的键值对必须存在的话,在指定类型后还应加上.isRequired
如果返回一个对象,对对象内部键值对有要求的话,例子如下:

    yourVarName: PropTypes.shape({ // 这里的shape是固定写法。
        var1: PropTypes.yourType,
        var2: PropTypes.yourType,
        // and so on
    })

5.钩子函数

在创建组件对象时,按顺序为constructor(), render(), componentDidMount()。 其中constructor用于初始化state,render用于渲染(不能在render主部分调用setState,只能在return里调用),componentDidMount在完成渲染后调用,用于发送网络请求和DOM操作。

当setState触发,或forceUpdate()触发,或当前组件作为子组件收到新的props,这三种情况之一出现组件的render就会重新调用,然后componentDidMount也会在render调用完之后被调用一次。且setState调用多次,render也只会重新渲染一次,因为setState是异步的,出于性能考虑. 但这里应该注意,这个componentDidMount内的setState必须要有个if条件判断,不然会死循环。这里建议if里写一个参数为prevProps,这个参数应该在componentDidMount (prevProps) {}这一步的形参中写入。当prevProps的某个值和this.props的对应值不相等的时候再执行内部函数,否则直接return。这么写避免死循环。

在组件完成功能被析构的时候,钩子函数为componentWillUnmount。这常常被用于清理setInterval(计时器)等调用系统函数的操作。

在类内还有一个钩子函数名为shouldComponentUpdate(nextProps, nextState).内部return true即为可重新渲染.这个钩子函数在重新渲染前执行,即shouldCOmponentUpdate后再执行新的render().这个钩子函数的第二个参数比较有趣,this.state是当前的state,而nextState是更新后的状态.这一钩子函数的return前一般加一个if,用来优化性能,有的东西不必重新渲染.


6. render props

这被用于某个组件中部分功能的公共模板化,类似把相同的代码抽象成一个函数。具体使用见下例:

代码语言:javascript
复制
class Son extends React.Component {
    state = {
        key: 1
    }
    dealWithState = () => {
        everything u like
    }
    render () {
        return this.props.render(this.state) //将state作为返回值返回给父类(这些state就是要复用的,暴露给组件外部),写法固定
    }
}

class Father extends React.Component {
    render () {
        return(
            <Son render={ //这个render只是变量名,一般都写成children而不写成render
                var => { //这里的var实际上就是Son里面的state
                    return(<p>{var.key}</p>)
                }
            }  />
        )
    }
}

在react中指定图片需要在头顶import pic from ‘yourPath’,然后在图片标签中的src写成src={pic}。

事实上这一封装操作相当于只依靠子组件的render函数中的返回值返回给父组件而已。相当于父索取信息,子返回信息。

建议对render props进行格式校验。即children: Proptypes.func.isRequired

7. 高阶组件

这个同样被用于模板化组件。分三步实现,以函数形式创建高阶组件模板,写出想要被套到模板上的组件和最终创建好了的组件。类似python装饰器。写法例子:

代码语言:javascript
复制
function withYourHOCName (WrappedComponent) { // 约定with开头
    class yourBasicProvider extends React.Component {
        state = {} // 想要返回的state
        yourDealWithState = () => {} // 想要对state处理的操作
        render () {
            return <WrappedComponent {...this.state} {...this.props}/> // 这一行固定写法,为了回传state,也为了能在最外层父类与yourTargetComponent通信
        }
    }
    yourBasicProvider.displayName = getDisplayName(WrappedComponent) // 让不同的套用有不同的名字,不然就都叫yourBasicProvider了,无法区分.
    return yourBasicProvider // 将基础逻辑的那个类返回
}

const yourTargetComponent = props => ( // 此处的props就是上面的state,这里声明了想要被套在HOC的组件
    <p>prop.yourProperties</p>
)

const yourResultComponent = withyourHOCName(yourTargetComponent) //类似装饰器的写法

得到最后的Component就是封装过yourBasicProvider的state这一个内容的高级组件。

8.路由

使用步骤: 导入。 import { BrowserRouter as Router, Route, Link, Routes } from ‘react-router-dom’ 用路由标签包裹想要使用路由的整个最外层。即<Router></Router>.这可以在上面声明最外层组件的时候实现,也可以在最后ReactDom渲染的时候在外面加上也可以。 指定路由的入口,即用户要点击的东西。代码为<Link to='/yourTargetPage'>指示的文字</Link>. 指定路由出口。代码为

代码语言:javascript
复制
<Routes>
<Route path='/yourTargetPage' element={<yourTargetComponent />} />
<Route> // route可以有多个,但必须指定这两个关键字,同时Route最外面一定被Routes包着。
</Routes>

这些关键字的名称都不能改变,且to和path里的是同样的文字。 这个Route写到哪里,渲染的element就在对应位置,并不是真实的跳转,有点像ajax动态请求的味道。

嵌套路由

react v6的新写法属实让人头大。不知道出于什么原因,我的Outlet无法使用。 嵌套路由大概描述一下就是,主页面只写父组件(这里是第一个Routes),父组件path必须后面跟/*。父组件内部还有一个Routes,里面放着一个Route,不过子组件的path不用带上父组件Route的path前缀。代码如下:

代码语言:javascript
复制
function App() {
  return (
    <Router>
      <div className="App">
        <ul>
          <li><Link to='home'>首页</Link></li>
          <li><Link to='citylist'>城市选择</Link></li>
        </ul>
        <Routes>
          <Route path='home/*' element={<Home />} />  //这里的Home是父组件
          <Route path='citylist' element={<CityList />} />
        </Routes>
      </div>
    </Router>
  )
}

at Home\index.js:
export default class Home extends React.Component {
    render () {
        return(
            <div>
                这是首页
                <nav>
                    <Link to='news'>go to news</Link>  //子组件,这里不写也行,直接输入url也可以跳转
                </nav>
                <Routes>
                    <Route path='news' element={<News />}/>  //这个path不必带前缀,且这里是第二个Routes
                </Routes>
            </div>
        )
    }
}

react引用原生js

最近在做项目需要用到这个。react按照惯例,代码会放在src里。但是我的需求是,引用外链js里的函数,这就要求我们用原生js写法。为此,找到public/下的index.html,插入

代码语言:javascript
复制
<script type='type' src='www.baidu.com'></script>  // 在这里定义了一个foo函数,比如说
<script>
var bar = (param) => {
    foo(param)
}
</script>

然后在src中的react框架js中,想调用这个foo函数就应该使用window.bar(YourParams)

react build之后部署在服务器

react build之前需要设置一个homepage在package.json里,设置为’./‘,不然index.html是白的。 而且要匹配路径的话,需要在router写一个attribute,其中具体为basename=’’,引号里是服务器匹配的路径。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-01-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 不再使用react.createElement
  • 2. map对数组批量操作
  • 3. 组件写法
    • state和setState注意事项
      • 可控组件
        • 组件onClick等事件传参
        • 4.组件通信
          • 父传递给子组件
            • 父组件调用子组件的信息
              • 兄弟组件相互通信
                • 跨组件通信
                  • props校验
                  • 5.钩子函数
                  • 6. render props
                  • 7. 高阶组件
                  • 8.路由
                  • 嵌套路由
                  • react引用原生js
                  • react build之后部署在服务器
                  相关产品与服务
                  内容识别
                  内容识别(Content Recognition,CR)是腾讯云数据万象推出的对图片内容进行识别、理解的服务,集成腾讯云 AI 的多种强大功能,对存储在腾讯云对象存储 COS 的数据提供图片标签、图片修复、二维码识别、语音识别、质量评估等增值服务。
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档