?本文目录?
1. setStatesetState更新状态的2种写法
2.lazyLoad路由组件的lazyLoad
3. Fragment使用作用
4.createContext()理解使用示例注意
本文被专栏【React–从基础到实战】收录
?坚持创作✏️,一起学习?,码出未来???!
1. setState
setState更新状态的2种写法
(1). setState(stateChange, [callback]) -----对象式的setState
this.setState({ count: count + 1 }, () => {
// render调用后
console.log(this.state.count)
});
1234
stateChange为状态改变对象,该对象可以体现出状态的更改;callback是可选的回调函数,它在状态更新完毕,页面也更新后(render调用后)才被调用
(2). setState(updater, [callback]) ----- 函数式的setState
this.setState((state, props) => {
console.log(state, props)
return { count: state.count + 1 }
});
1234
updater为返回stateChange对象的函数;updater可以接收到state和props;callback是可选的回调函数,它在状态更新、页面也更新后(render调用后)才被调用
总结:
对象式的setState是函数式的setState的简写方式(语法糖) 使用原则: (1)如果新状态不依赖于原状态 ==== 使用对象方式 (2)如果新状态依赖于原状态 ==== 使用函数方式 (3)如果需要在setState()执行后获取最新的状态数据,要在第二个callback函数中读取 React状态的更新是异步的!!
2.lazyLoad
路由组件的lazyLoad
引入lazy函数和Suspense组件
import React, { Component, lazy, Suspense } from 'react'
1
实现路由懒加载
// 1.通过React的lazy函数配合import()函数动态加载路由组件 ===> 路由组件代码会被分开打包
const Login = lazy(() => import('@/pages/Login'))
// 2. 通过<Suspense>指定在加载得到路由打包文件前显示一个自定义loading界面
<Suspense fallback={<h1>loading</h1>}>
<Switch>
<Route path="/xxx" component={xxx}/>
<Redirect to="/login"/>
</Switch>
</Suspense>
12345678910
3. Fragment
使用
// Componment
import React, { Component, Fragment } from 'react'
import Demo from './components/4_fragment'
export default class App extends Component {
render() {
return (
<Fragment>
<Demo />
</Fragment>
)
}
}
// FC
import React, { Fragment } from 'react'
export default function Demo() {
return (
<Fragment>
<input type="text" />
<input type="text" />
</Fragment>
)
}
其实还可以...
import React from 'react'
export default function Demo() {
return (
<>
<input type="text" />
<input type="text" />
</>
)
}
12345678910111213141516171819202122232425262728293031323334353637
作用
可以不用必须有一个真实的DOM根标签了
4.createContext()
理解
一种组件间通信方式,常用于【祖组件】与【后代组件】间通信
使用
创建Context容器对象: const Xxxcontext = React.createContext()例如:进口气动球阀
1 渲染子组件时,外面包裹xxxContext.Provider,通过value属性给后代组件传递数据: <XxxContext.Provider value={数据}>
子组件
</XxxContext.Provider>
123 后代组件读取数据: // 第一种方式:仅适用于类组件
static contextType = xxxContext // 声明接收context
this.context // 读取context中的value数据
// 第二种方式:函数组件与类组件都可以
<xxxContext.Consumer>
{
value => ( //value就是context中的value数据
要显示内容
)
}
</xxxContext.Consumer>
123456789101112
示例
A组件是父组件;B组件是子组件;C组件是孙组件
A组件中初始化了state,里面有一个username属性值为tom;
孙组件C要使用A组件传递过来的username属性。
import React, { Component } from 'react'
import './index.css'
// 创建一个用于保存数据的上下文
const MyContext = React.createContext()
export default class A extends Component {
state = { username: 'tom' }
render() {
return (
<div className='parent'>
<h3>我是A组件</h3>
<h4>我的用户名是:{this.state.username}</h4>
<MyContext.Provider value={this.state.username}>
<B />
</MyContext.Provider>
</div>
)
}
}
class B extends Component {
render() {
return (
<div className='child'>
<h3>我是B组件</h3>
<C />
</div>
)
}
}
class C extends Component {
// 声明接收context
static contextType = MyContext
render() {
console.log(this)
return (
<div className='grand'>
<h3>我是C组件</h3>
<h4>我从A组件接收到的用户名:{this.context}</h4>
</div>
)
}
}
12345678910111213141516171819202122232425262728293031323334353637383940414243444546
若孙组件C为函数式组件FC:
function C() {
return (
<div className='grand'>
<h3>我是C组件</h3>
<h4>我从A组件接收到的用户名:
<MyContext.Consumer>
{
value => {
return value
}
}
</MyContext.Consumer>
</h4>
</div>
)
}
12345678910111213141516
注意
在应用开发中一般不用context,一般都用它来封装react插件;
比如:react-redux库底层就使用到了context…
我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当
鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende
我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("
我一直致力于让我们的Rails2.3.8应用程序在JRuby下正确运行。一切正常,直到我启用config.threadsafe!以实现JRuby提供的并发性。这导致lib/中的模块和类不再自动加载。使用config.threadsafe!启用:$rubyscript/runner-eproduction'pSim::Sim200Provisioner'/Users/amchale/.rvm/gems/jruby-1.5.1@web-services/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:105:in`co
我想这样组织C源代码:+/||___+ext||||___+native_extension||||___+lib||||||___(Sourcefilesarekeptinhere-maycontainsub-folders)||||___native_extension.c||___native_extension.h||___extconf.rb||___+lib||||___(Rubysourcecode)||___Rakefile我无法使此设置与mkmf一起正常工作。native_extension/lib中的文件(包含在native_extension.c中)将被完全忽略。
我们目前正在为ROR3.2开发自定义cms引擎。在这个过程中,我们希望成为我们的rails应用程序中的一等公民的几个类类型起源,这意味着它们应该驻留在应用程序的app文件夹下,它是插件。目前我们有以下类型:数据源数据类型查看我在app文件夹下创建了多个目录来保存这些:应用/数据源应用/数据类型应用/View更多类型将随之而来,我有点担心应用程序文件夹被这么多目录污染。因此,我想将它们移动到一个子目录/模块中,该子目录/模块包含cms定义的所有类型。所有类都应位于MyCms命名空间内,目录布局应如下所示:应用程序/my_cms/data_source应用程序/my_cms/data_ty
我有一个要在我的Rails3项目中使用的数组扩展方法。它应该住在哪里?我有一个应用程序/类,我最初把它放在(array_extensions.rb)中,在我的config/application.rb中我加载路径:config.autoload_paths+=%W(#{Rails.root}/应用程序/类)。但是,当我转到railsconsole时,未加载扩展。是否有一个预定义的位置可以放置我的Rails3扩展方法?或者,一种预先定义的方式来添加它们?我知道Rails有自己的数组扩展方法。我应该将我的添加到active_support/core_ext/array/conversion
我想编写一个ruby脚本来递归复制目录结构,但排除某些文件类型。因此,给定以下目录结构:folder1folder2file1.txtfile2.txtfile3.csfile4.htmlfolder2folder3file4.dll我想复制这个结构,但不包含.txt和.cs文件。因此,生成的目录结构应如下所示:folder1folder2file4.htmlfolder2folder3file4.dll 最佳答案 您可以使用查找模块。这是一个代码片段:require"find"ignored_extensions=[".cs"
这个问题有两个部分。在RubyProgrammingLanguage一书中,有一个使用模块扩展字符串对象和类的示例(第8.1.1节)。第一个问题。为什么如果您使用新方法扩展类,然后创建该类的对象/实例,则无法访问该方法?irb(main):001:0>moduleGreeter;defciao;"Ciao!";end;end=>nilirb(main):002:0>String.extend(Greeter)=>Stringirb(main):003:0>String.ciao=>"Ciao!"irb(main):004:0>x="foobar"=>"foobar"irb(main):
我有一个将某些事件写入队列的Rails3应用。现在我想在服务器上创建一个服务,每x秒轮询一次队列,并按计划执行其他任务。除了创建ruby脚本并通过cron作业运行它之外,还有其他稳定的替代方案吗? 最佳答案 尽管启动基于Rails的持久任务是一种选择,但您可能希望查看更有序的系统,例如delayed_job或Starling管理您的工作量。我建议不要在cron中运行某些东西,因为启动整个Rails堆栈的开销可能很大。每隔几秒运行一次它是不切实际的,因为Rails上的启动时间通常为5-15秒,具体取决于您的硬件。不过,每天这样做几