最近react-native(以下簡(jiǎn)稱(chēng)rn)的技術(shù)越來(lái)越活,國(guó)內(nèi)的使用情況也越來(lái)越多,國(guó)內(nèi)的氛圍也越來(lái)越好收壕,其實(shí)我是從去年就接觸了一下rn妓灌,當(dāng)時(shí)我學(xué)習(xí)了一個(gè)多星期轨蛤,然后剛好處于要換工作就沒(méi)有學(xué)習(xí)了,剛好最近有點(diǎn)空閑的時(shí)間虫埂,就再次去學(xué)習(xí)祥山,只能說(shuō)rn的更新速度太快了,很多之前的寫(xiě)法都變了掉伏,只能從頭開(kāi)始缝呕,但是一整個(gè)項(xiàng)目都采用rn來(lái)構(gòu)建還不是很現(xiàn)實(shí),所以國(guó)內(nèi)很多的也是集成rn斧散,所以我也來(lái)湊湊熱鬧供常。
1:添加依賴(lài)
compile "com.facebook.react:react-native:+" // From node_modules
在項(xiàng)目的build.gradle下添加
allprojects {
repositories {
mavenLocal()
jcenter()
maven {
// All of React Native (JS, Android binaries) is installed from npm
url "$rootDir/node_modules/react-native/android"
}
}
}
2:在app的實(shí)現(xiàn)ReactApplication接口,以下是部分代碼
*/
public class App extends Application implements ReactApplication{
private static App appContext;
private static AppComponent mAppComponent;
private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
@Override
protected boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage()
);
}
};
3:在AndroidManifest.xml加入
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity"/>
加入以下的activity可以在搖一搖出現(xiàn)rn的配置頁(yè)面。
4:寫(xiě)個(gè)activity來(lái)繼承ReactActivity
public class MainActivity extends ReactActivity {
/**
* Returns the name of the main component registered from JavaScript.
* This is used to schedule rendering of the component.
*/
@Override
protected String getMainComponentName() {
return "MyHot";
}
}
在這里介紹一篇大帥寫(xiě)的React Native 0.31 Bundle 預(yù)加載優(yōu)化主要解決從原生頁(yè)面到rn頁(yè)面會(huì)有短暫的白屏鸡捐。使用方法
dependencies {
compile "com.github.moduth:react-native-preloader:0.31.0"
}
把之前繼承ReactActivity變成繼承MrReactActivity
public class MyReactActivity extends MrReactActivity {
public static final ReactInfo reactInfo = new ReactInfo("MyHot", null);
@Override
protected String getMainComponentName() {
return reactInfo.getMainComponentName();
}
@Override
public ReactInfo getReactInfo() {
return reactInfo;
}
}
在調(diào)用rn頁(yè)面調(diào)用
ReactPreLoader.init(this, MyReactActivity.reactInfo);
這樣就能很好的解決上述的問(wèn)題栈暇。
在rn中我引入了redux,以下就貼出關(guān)鍵行代碼箍镜,在最外層
import configureStore from './store/store.js'
import App from './containes/App.js'
const store = configureStore();
class rootApp extends Component {
render() {
return (
<Provider store={store}>
<App/>
</Provider>
)
}
}
export default rootApp;
同時(shí)個(gè)actions的文件夾里面放著各種的操作源祈,以下是我的newsList的代碼
import * as types from "../constants/ActionTypes.js";
import * as Services from "../utils/Services.js";
import {
NEW_LIST
} from "../constants/Urls.js";
export function fetchNews(loading, isRefresh, isLoadMore, pn) {
return dispatch => {
dispatch(fetchNewsList(loading, isRefresh, isLoadMore));
Services.getNewList(NEW_LIST, pn)
.then(result => {
dispatch(receiveNewsList(result));
});
}
}
function fetchNewsList(loading, isRefresh, isLoadMore) {
return {
type: types.FE_NEWLIST,
loading: loading,
isRefresh: isRefresh,
isLoadMore: isLoadMore
};
}
function receiveNewsList(newsList) {
return {
type: types.RE_NEWLIST,
newsList: newsList
}
}
還有就是ruducers文件夾下的和action所對(duì)應(yīng)的
import * as types from '../constants/ActionTypes';
const initialState = {
loading: true,
isRefresh: false,
isLoadMore: false,
newsList: []
}
export default function revicesNewsList(state = initialState, action) {
switch (action.type) {
case types.FE_NEWLIST:
return Object.assign({}, state, {
loading: action.loading,
isRefresh: action.isRefresh,
isLoadMore: action.isLoadMore,
});
case types.RE_NEWLIST:
return Object.assign({}, state, {
loading: false,
isRefresh: false,
isLoadMore: false,
newsList: state.isLoadMore ? state.newsList.concat(action.newsList) : action.newsList,
});
default:
return state;
}
}
還有就是一個(gè)轉(zhuǎn)化的
import {
connect
} from 'react-redux';
import News from "../pages/News.js";
import {
bindActionCreators
} from 'redux';
import * as newsAction from '../actions/newsList.js';
class NewsContainer extends Component {
render() {
return (
<News {...this.props} />
);
}
}
function mapStateToProps(state) {
const {
news
} = state;
return {
news
}
}
function mapDispatchToProp(dispatch) {
return {
actions: bindActionCreators(newsAction, dispatch)
};
}
export default connect(mapStateToProps, mapDispatchToProp)(NewsContainer);
這樣在使用的時(shí)候就是調(diào)用action的方法
componentDidMount() {
const {
actions
} = this.props;
actions.fetchNews(true, false, false, page);
}
接受到數(shù)據(jù)
render() {
const {
navigator,
news
} = this.props;
return (
<View style={styles.container}>
<Header title="體育" navigator= {navigator}/>
{this.renderContent()}
</View>
)
}
這樣以后要是添加新的頁(yè)面就很清楚了,在action里面添加動(dòng)作色迂,在reducers添加action的處理器香缺,這樣就很清晰了。
我添加了一個(gè)Services歇僧,來(lái)獲取數(shù)據(jù)
const HOST = "http://apis.baidu.com/";
import FetchHttpClient, {
query,
header
} from 'fetch-http-client';
import {
toastShort
} from "./ToastUtil.js";
let client = new FetchHttpClient(HOST);
export function getNewList(url, pnSize) {
return getClient().get(url, {
query: {
num: 10,
pn: pnSize
},
}).then(filterJSON)
.then(filterStatus)
.catch((error) => {
toastShort('網(wǎng)絡(luò)發(fā)生錯(cuò)誤,請(qǐng)重試!')
});
}
function getClient() {
client.addMiddleware(query());
client.addMiddleware(request => {
request.options.headers['apikey'] = 'ff27ef67506b2c0738a3252b01f8d564';
});
return client;
}
function filterStatus(res) {
if (res.code === 200) {
return res.newslist;
} else {
toastShort(res.msg);
}
}
function filterJSON(res) {
return res.json();
}
本人rn的水平有限图张,要是有不對(duì)的地方,還請(qǐng)指出和諒解诈悍。本文的所以代碼在github地址祸轮,歡迎star。