‘壹’ 使用react框架怎么进行组件的递归调用
JS有一种语法,叫做函数的尾递归(具体用法自己查)。
react组件本身不具备这些功能,需要自己用js控制业务逻辑。
例如有一个显示评论内容的组件,当客户端请求成功,并且返回多级json结构的时候,客户端就需要先判断结构有几层,然后用js控制加载的组件层次,将数据props过去。
一般的情况下,层数只有2,参考UC的评论模式,假设我写了一个评论,则为顶层,然后你可以在我的评论下面评论,这样就有了2层,但是别人又可以回复你的评论,这时就要注意了,别人回复你的评论还是在第2层,也就是说,任何人的评论都只在顶层之下的同一层,不会超出2层的结构,这样做才合理。像你说的那种,就是可以有几十上百层评论结构,那样显示就不好看了。。
‘贰’ reactjs怎么在方法里面调方法
调用函数 前加 this.
change(){
this.ff()
}
这样
‘叁’ 如何在React中调用微信的jsSDK
1. 微信JSSDK使用步骤简介
我们既然是在做基于微信的开发,当然就离不开微信的开发文档了。开始之前希望大家能先去看下《微信JS-SDK说明文档》。那么我们怎么样才能用上微信的JSSDK呢?以下基本步骤就是基于该文档的。
需要注意的是,如果本人下面的描述你看的有点云里雾里的话,我建议你:
回头看下本系列《小白学react》的历史基础文章,特别是《小白学react之altjs的Action和Store》以及《小白学react之打通React Component任督二脉》,或/和:
直接跳过我的描述,在文章后面下载最新的源码,先阅读源码,碰到问题再反过来看文章的描述。
步骤一:绑定域名
先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。
备注:登录后可在“开发者中心”查看对应的接口权限。
这里绑定的时候需要注意不要带前面的http协议头。写法跟上一篇《小白学react之网页获取微信用户信息》中的网页回调域名设置的写法是一样的。
步骤二:引入JS文件
在需要调用JS接口的页面引入如下JS文件,(支持https):
请注意,如果你的页面启用了https,务必引入 :
,否则将无法在iOS9.0以上系统中成功使用JSSDK
因为我们的index.html是通过ejs模版生成的,所以我们只需要在我们的index.ejs中的body部分末尾加入相应的微信jssdk库的引用就好了。
步骤三:通过config接口注入权限验证配置
所有需要使用JS-SDK的页面必须先注入配置信息,否则将无法调用(同一个url仅需调用一次,对于变化url的SPA的web app可在每次url变化时进行调用,目前Android微信客户端不支持pushState的H5新特性,所以使用pushState来实现web app的页面会导致签名失败,此问题会在Android6.2中修复)。
这一步的关键是如何生成正确的签名。这里微信jssdk文档中有给出不同语言版本的签名算法示例大家可以参考。往下我们也会就github上的一个签名算法的封装进行学习。
在我们的实战过程中,签名会在服务器端发生。
react客户端会像之前的获取微信用户信息一样,通过一个restfulApi调用服务器端的api,然后由服务器来生成对应的签名,然后将签名信息返回给客户端。
客户端获取到上面wx.config示例代码中的签名相关信息后,就会调用一个Alt的Action,来触发将获取回来的信息保存到一个跟该Action绑定的jssdk状态管理的Store里面。然后就可以调用wx.config来配置我们需要用到的JS接口列表了。
注意这里的wx这个对象是通过上一步的JS文件引入进来的。我们在react的客户端代码中可以直接通过window.wx对其进行引用:
步骤四:通过ready接口处理成功验证
随后,react客户端负责jssdk状态管理的store会调用wx.ready来监听config配置是否成功,如果成功的话,就会将该store的一个ready状态设置成true。
这样的话,通过AltContainer绑定了该store的相应的Component组件就能知道响应的jssdk的api是否已经准备就绪,可以进行调用了。
步骤五:通过error接口处理失败验证
同理,如果如果配置失败的话,那么就在wx.error这个监听接口中将ready状态设置成false。
2. 生成签名
如前面所述,我们需要用到jssdk的页面必须要要注入调用到的api的配置信息。
而注入JS接口到页面时,我们可以看到,还需要使用到其他一些信息。其中appId我们可以从公众号管理后台获得。signature是跟所访问页面的url关联的一个签名,它有专门的一套算法来生成。另外两个参数nonceStr和signature都是在签名的过程中生成的。
这里通过wx.config传进去这些参数,主要是为了让微信去判断我们生成的签名和微信通过这些信息生成的签名是否一致,如果不一致的话,那么注入到该页面的jsApiListj就失败。
那么我们在服务器这边的签名算法是如何的呢?根据微信开发文档我们需要提供以下4个参数,然后通过sha1算发来生成对应的签名:
noncestr:一个随机字符串,我们随便填写
jsapi_ticket:jsapi_ticket是公众号用于调用微信JS接口的临时票据
timestamp: 签名时间戳。注意这个时间戳需要和上面传入wx.config的时间戳一致
url: 调用JS接口页面的完整URL。我们可以从react客户端通过location.href获得,并传给服务器端
那么这里主要需要解决的就是如何获得jsapi_ticket这个临时票据了。
根据文档的描述,我们可以通过以下这个接口获得:
cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi
从中可以看到,我们调用这个接口首先要获得一个access_token。这里微信也有相应的api来处理。
cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
这里需要用到我们的微信公众号的appId和secret,这些我们都是已知的,所以好办。
那么,也就是说,我们其实只需要提供我们的微信公众号的appId和secret,就能获取到access_token,从而就会获得我们需要的jsapi_ticket。
这里我们参考下github上一个示例(wechat-sdk-demo )的签名的实现。其传入的参数有两个,其中:
url: react客户端传进来的需要注入jsapi的页面url
callback: 一个回调函数,接受一个json格式的参数。主要是用来将生成的签名信息等回传给上层调用函数。
这里的流程和我们刚才描述的并无二致。首先是通过appId和secret获得调用获取jsapi_ticket的access_token,然后通过该access_token获得我们签名需要用到的jsapi_ticket。noncestr我们是提前随便填写好的。timestamp的算法也比较简单。
最后就是通过sha1这个库提供的方法,将jsapi_ticket,noncestr,timestamp和页面url进行sha1签名,然后将以上这些信息通过callback返回给上层调用函数。
那么我们往下看下我们的上层调用函数。其实就是我们的express路由:
根据微信开发文档需求,我们首先需要将传进来的url的锚点后面的数据给去掉,保留前面的有效部分。
然后就是调用上面的sign方法来生成签名。上面的签名方法最后传进来的json数据就是这里的signatureMap。我们最终会将这些数据发送回react客户端。
同时,通过上面的wx.config的示例,我们知道还需要用到微信公众号的appId。所以这里一并将其放到signatureMap中进行返回。
那么到此为止,react客户端调用服务端的"/api/signature"返回的数据示例如下:
3. 客户端获取签名信息
3.1 获取签名信息并注入jssdk
和之前的获取微信用户信息一样,我们这里会建立一个新的Source文件WechatSdkSource.js来调用远程服务器的"/api/signature"接口:
这里传进来的url由下面将要谈及的上层函数所生成。整个流程就没有什么好说的了,说白了就是通过相应的库发送一个带有url的query参数的请求到服务器端来请求签名信息,相信有跟着这个系列文章的朋友都是很清楚的了。
最终请求成功返回的时候就会调用WechatSdkActions的updateSignatureMap这个Action。
而这个action就会触发所监听的WechatSdkStore的onUpdateSignatureMap这个回调。
‘肆’ react 父组件怎么调用子组件的方法
可以通过向子组件传入一个修改state的函数,比如如下代码:
父组件:
class Father extends Component {
construtor(props){
super(props);
this.state={
name: 'Peter',
age: '26'
}
}
onChangeState(stateName){
this.setState(stateName)
}
render(){
<p>姓名:{this.state.name}</p>
<p>年龄:{this.state.age}</p>
<Child onClicked={this.onChangeState.bind(this)}/>
}
}
子组件:
class Child extends Component {
render(){
<Button onClicked={()=>this.props.onClicked({name: 'John'})}/>
}
}
‘伍’ React 组件上调用方法如何传递参数,除了匿名函数用更好的方法吗
Java 应用程序按值传递参数(引用类型或基本类型),其实都是传递他们的一份拷贝.而不是数据本身.(不是像 C++ 中那样对原始值进行操作。)
例1:
Java代码
//在函数中传递基本数据类型,
public class Test {
public static void change(int i, int j) {
int temp = i;
i = j;
j = temp;
}
public static void main(String[] args) {
int a = 3;
int b = 4;
change(a, b);
System.out.println("a=" + a);
System.out.println("b=" + b);
}
}
结果为:
a=3
b=4
原因就是 参数中传递的是 基本类型 a 和 b 的拷贝,在函数中交换的也是那份拷贝的值 而不是数据本身;
例2:
Java代码
//传的是引用数据类型
public class Test {
public static void change(int[] counts) {
counts[0] = 6;
System.out.println(counts[0]);
}
public static void main(String[] args) {
int[] count = { 1, 2, 3, 4, 5 };
change(count);
}
}
在方法中 传递引用数据类型int数组,实际上传递的是其引用count的拷贝,他们都指向数组对象,在方法中可以改变数组对象的内容。即:对复制的引用所调用的方法更改的是同一个对象。
‘陆’ react native static怎么调用外部方法
Annotation所修饰的对象范围:Annotation可被用于packages、types(类、接口、枚举、Annotation类型)、类型成员(方法、构造方法、成员变量、枚举值)、方法参数和本地变量(如循环变量、catch参数)。在Annotation类型的声明中使用了target可
‘柒’ react中怎么调用别人的接口进行跳转
RN自带了一个非常优雅的网络操作库fetch,下面的这个例子从gankio的接口拿到了美女图片的url然后通过state 传给列表组件,列表里返回图片组件显示图片。网络数据获取方法写在componentDidMount中,这个方法是组件生命周期中需要调用的一个方法。
class AwesomeProject extends Component {// 初始化模拟数据
constructor(props) {
super(props);
const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => {r1 !== r2}});
this.state = {
dataSource: ds,
load:false,
text:''
};
}
//耗时操作放在这里面
componentDidMount(){
this.getNet();
}
getNet(){
fetch('http://gank.io/api/search/query/listview/category/福利/count/10/page/1')//请求地址
.then((response) => response.json())//取数据
.then((responseText) => {//处理数据
//通过setState()方法重新渲染界面
this.setState({
//改变加载ListView
load: true,
//设置数据源刷新界面
dataSource: this.state.dataSource.cloneWithRows(responseText.results),
})
})
.catch((error) => {
console.warn(error);
}).done();
}
render() {
if(this.state.load){
return (
<View style={{flex: 1, paddingTop: 22}}>
<ListView
dataSource={this.state.dataSource}
renderRow={(rowData)=>
<View>
<Image
style={{ width: 400, height: 250, marginTop: 5 }}
source={{uri:rowData.url}}/>
</View>}
/>
</View>
);
} else{
return(
<View>
<Text>loading......</Text>
</View>
);
}
}
}
‘捌’ react 调用方法
情况一:
constructor(props) { super(props); this.login = this.login.bind(this);
}
login(a,b,c) { console.log(this);//打印这个组件本身
console.log(a);//打印111111
console.log(b);//undefined
console.log(c);//undefined}
<button onClick={()=>{this.login(111111)}} />
情况二:
constructor(props) { super(props); this.login = this.login.bind(this);
}
login(a,b,c) { console.log(this);//打印这个组件本身
console.log(a);//打印Proxy对象:Proxy里面可以获得dom元素
console.log(b);//打印event
console.log(c);//undefined}
<button onClick={this.login} />
情况三:
constructor(props) { super(props); // this.login = this.login.bind(this);}
login(a,b,c) { console.log(this);//打印这个组件本身,说明我们用箭头函数的时候,不需要bind(this),react自动把this指向了组件自己,
console.log(a);//打印出了111111
console.log(b);//undefined
console.log(c);//undefined}
<button onClick={()=>{this.login(111111)}} />
情况四:
constructor(props) { super(props); // this.login = this.login.bind(this);}
login(a,b,c) { console.log(this);//打印null,这是react最常见的坑,this本来指向window,但是经过react初始化之后,指向了null;
console.log(a);//打印Proxy对象:Proxy里面可以获得dom元素
console.log(b);//打印event
console.log(c);
}
<button onClick={this.login} />
情况五:
constructor(props) { super(props); // this.login = this.login.bind(this);}
login(a,b,c) { console.log(this);//打印这个组件本身
console.log(a);//undefined
console.log(b);//undefined
console.log(c);//undefined}
<button onClick={()=>{this.login()}} />
情况六:(可以算作es5的最佳实践,用的es5的方法,拿到所有参数)
constructor(props) { super(props); // this.login = this.login.bind(this);
this.login=(a,b,c)=>{ console.log(this);//打印这个组件本身
console.log(a);//111111
console.log(b);//打印Proxy对象:Proxy里面可以获得dom元素
console.log(c);//打印event:
}
}
<button onClick={this.login.bind(this,111111)} />
最佳实践:(for es6) 老版本
constructor(props) { super(props); // this.login = this.login.bind(this);}
login(type,event,proxy) { console.log(this);//打印这个组件本身
console.log(event);//打印event:
console.log(proxy);//打印Proxy对象,event详情请查验es6}
<button onClick={()=>{let target=this, handler={};this.login('boss',event,new Proxy(target, handler))}}/>
最佳实践:2018(需要传参)
constructor(props) { super(props);
}
login=(num, evt)=>{ console.log(num);//打印传参
console.log(evt);//打印event:}
<button onChange={this.login.bind(null, 111)}/>
最佳实践:2018(不需要传参)
constructor(props) { super(props);
}
login=( evt)=>{ console.log(evt);//打印event:}
<button onChange={this.login}/>