- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
你好,我还是 react native 的新手,我很困惑如何使用 react redux,尤其是对于 ignite 模板。我遵循本教程 https://medium.com/skyshidigital/interaksi-api-dengan-ignite-react-native-f83bf35a23f5 .这是我最新的错误“检查时未捕获”,“take(patternOrChannel): patternOrChannel is undefined”。请帮助告诉我我的代码哪里出错了。
API.js:
// a library to wrap and simplify api calls
import apisauce from 'apisauce'
// our "constructor"
const create = (baseURL = 'http://localhost:4200/') => {
// ------
// STEP 1
// ------
//
// Create and configure an apisauce-based api object.
//
const api = apisauce.create({
// base URL is read from the "constructor"
baseURL,
// here are some default headers
headers: {
'Cache-Control': 'no-cache'
},
// 10 second timeout...
timeout: 10000
})
// ------
// STEP 2
// ------
//
// Define some functions that call the api. The goal is to provide
// a thin wrapper of the api layer providing nicer feeling functions
// rather than "get", "post" and friends.
//
// I generally don't like wrapping the output at this level because
// sometimes specific actions need to be take on `403` or `401`, etc.
//
// Since we can't hide from that, we embrace it by getting out of the
// way at this level.
//
const getRoot = () => api.get('')
const getRate = () => api.get('rate_limit')
const getUser = (username) => api.get('search/users', {q: username})
const getUsers = () => api.get('/users')
// ------
// STEP 3
// ------
//
// Return back a collection of functions that we would consider our
// interface. Most of the time it'll be just the list of all the
// methods in step 2.
//
// Notice we're not returning back the `api` created in step 1? That's
// because it is scoped privately. This is one way to create truly
// private scoped goodies in JavaScript.
//
return {
// a list of the API functions from step 2
getRoot,
getRate,
getUser,
getUsers
}
}
// let's return back our create method as the default.
export default {
create
}
UsersRedux.js
import { createReducer, createActions } from 'reduxsauce'
import Immutable from 'seamless-immutable'
/* ------------- Types and Action Creators ------------- */
const { Types, Creators } = createActions({
usersRequest: null,
usersSuccess: ['data'],
usersFailure: null
})
export const UsersTypes = Types
export default Creators
/* ------------- Initial State ------------- */
export const INITIAL_STATE = Immutable({
data: null,
fetching: null,
payload: null,
error: null
})
/* ------------- Reducers ------------- */
// request the data from an api
export const request = (state, { data }) =>
state.merge({ fetching: true, payload: null })
// successful api lookup
export const success = (state, action) => {
const { payload } = action
return state.merge({ fetching: false, error: null, data })
}
// Something went wrong somewhere.
export const failure = state =>
state.merge({ fetching: false, error })
/* ------------- Hookup Reducers To Types ------------- */
export const reducer = createReducer(INITIAL_STATE, {
[Types.USERS_REQUEST]: request,
[Types.USERS_SUCCESS]: success,
[Types.USERS_FAILURE]: failure
})
来自 Redux 文件夹的 index.js:
import { combineReducers } from 'redux'
import configureStore from './CreateStore'
import rootSaga from '../Sagas/'
export default () => {
/* ------------- Assemble The Reducers ------------- */
const rootReducer = combineReducers({
nav: require('./NavigationRedux').reducer,
github: require('./GithubRedux').reducer,
login: require('./LoginRedux').reducer,
search: require('./SearchRedux').reducer,
users: require('./UsersRedux').reducer
})
return configureStore(rootReducer, rootSaga)
}
UsersSagas.js:
/* ***********************************************************
* A short word on how to use this automagically generated file.
* We're often asked in the ignite gitter channel how to connect
* to a to a third party api, so we thought we'd demonstrate - but
* you should know you can use sagas for other flow control too.
*
* Other points:
* - You'll need to add this saga to sagas/index.js
* - This template uses the api declared in sagas/index.js, so
* you'll need to define a constant in that file.
*************************************************************/
import { call, put } from 'redux-saga/effects'
import UsersActions from '../Redux/UsersRedux'
export function * getUsers (api, action) {
const { data } = action
// make the call to the api
const response = yield call(api.getUsers, data)
// success?
if (response.ok) {
// You might need to change the response here - do this with a 'transform',
// located in ../Transforms/. Otherwise, just pass the data back from the api.
yield put(UsersActions.usersSuccess(response.data))
} else {
yield put(UsersActions.usersFailure())
}
}
来自 Sagas 的 index.js
import { takeLatest, all } from 'redux-saga/effects'
import API from '../Services/Api'
import FixtureAPI from '../Services/FixtureApi'
import DebugConfig from '../Config/DebugConfig'
/* ------------- Types ------------- */
import { StartupTypes } from '../Redux/StartupRedux'
import { GithubTypes } from '../Redux/GithubRedux'
import { LoginTypes } from '../Redux/LoginRedux'
import { UsersTypes } from "../Redux/UsersRedux";
/* ------------- Sagas ------------- */
import { startup } from './StartupSagas'
import { login } from './LoginSagas'
import { getUserAvatar } from './GithubSagas'
import { getUsers } from "./UsersSagas"
/* ------------- API ------------- */
// The API we use is only used from Sagas, so we create it here and pass along
// to the sagas which need it.
const api = DebugConfig.useFixtures ? FixtureAPI : API.create()
/* ------------- Connect Types To Sagas ------------- */
export default function * root () {
yield all([
// some sagas only receive an action
takeLatest(StartupTypes.STARTUP, startup),
takeLatest(LoginTypes.LOGIN_REQUEST, login),
// some sagas receive extra parameters in addition to an action
takeLatest(GithubTypes.USER_REQUEST, getUserAvatar, api),
takeLatest(UsersTypes.USER_REQUEST, getUsers, api)
])
}
登录屏幕.js:
import React, { PropTypes } from "react";
import { View, ScrollView, Text, TextInput, TouchableOpacity, Image, Keyboard, LayoutAnimation } from "react-native";
import { connect } from "react-redux";
import Styles from "./Styles/LoginScreenStyles";
import { Images, Metrics } from "../Themes";
import LoginActions from "../Redux/LoginRedux";
import { Button, Text as NBText, Contant, Form, Item, Input, Label, StyleProvider } from "native-base";
import buttonTheme from '../../native-base-theme/components/';
import commonColor from '../../native-base-theme/variables/commonColor';
import UsersActions from "../Redux/UsersRedux";
class LoginScreen extends React.Component {
static propTypes = {
dispatch: PropTypes.func,
fetching: PropTypes.bool,
attemptLogin: PropTypes.func,
getUsers: PropTypes.func
};
isAttempting = false;
keyboardDidShowListener = {};
keyboardDidHideListener = {};
constructor(props) {
super(props);
this.props.getUsers();
this.state = {
username: "",
password: "",
visibleHeight: Metrics.screenHeight,
topLogo: { width: Metrics.screenWidth - 40 },
};
this.isAttempting = false;
}
componentWillReceiveProps(newProps) {
this.forceUpdate();
// Did the login attempt complete?
if (this.isAttempting && !newProps.fetching) {
this.props.navigation.goBack();
}
}
componentWillMount() {
// Using keyboardWillShow/Hide looks 1,000 times better, but doesn't work on Android
// TODO: Revisit this if Android begins to support - https://github.com/facebook/react-native/issues/3468
this.keyboardDidShowListener = Keyboard.addListener("keyboardDidShow", this.keyboardDidShow);
this.keyboardDidHideListener = Keyboard.addListener("keyboardDidHide", this.keyboardDidHide);
}
componentWillUnmount() {
this.keyboardDidShowListener.remove();
this.keyboardDidHideListener.remove();
}
keyboardDidShow = e => {
// Animation types easeInEaseOut/linear/spring
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
let newSize = Metrics.screenHeight - e.endCoordinates.height;
this.setState({
visibleHeight: newSize,
topLogo: { width: 100, height: 70 },
});
};
keyboardDidHide = e => {
// Animation types easeInEaseOut/linear/spring
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
this.setState({
visibleHeight: Metrics.screenHeight - 100,
topLogo: { width: Metrics.screenWidth - 40 },
});
};
handlePressLogin = () => {
// const { username, password } = this.state
// this.isAttempting = true
// attempt a login - a saga is listening to pick it up from here.
// this.props.attemptLogin(username, password);
this.props.navigation.navigate("LaunchScreen");
};
handlePressRegister = () => {
// const { username, password } = this.state
// this.isAttempting = true
// attempt a login - a saga is listening to pick it up from here.
// this.props.attemptLogin(username, password);
this.props.navigation.navigate("RegisterScreen");
};
handleChangeUsername = text => {
this.setState({ username: text });
};
handleChangePassword = text => {
this.setState({ password: text });
};
render() {
const { username, password } = this.state;
const { fetching } = this.props;
const editable = !fetching;
const textInputStyle = editable ? Styles.textInput : Styles.textInputReadonly;
return (
<ScrollView
contentContainerStyle={{ justifyContent: "center" }}
style={[Styles.container, { height: this.state.visibleHeight }]}
keyboardShouldPersistTaps="always"
>
<Image source={require("../Images/tuku_omah_logo_login.jpeg")} style={[Styles.topLogo, this.state.topLogo]} />
<View style={Styles.form}>
<Form>
<Item stackedLabel>
<Label>Username</Label>
<Input
ref="username"
value={username}
editable={editable}
keyboardType="default"
returnKeyType="next"
autoCapitalize="none"
autoCorrect={false}
onChangeText={this.handleChangeUsername}
underlineColorAndroid="transparent"
onSubmitEditing={() => this.password._root.focus()}
/>
</Item>
<Item stackedLabel>
<Label>Password</Label>
<Input
ref={ref => (this.password = ref)}
value={password}
editable={editable}
keyboardType="default"
returnKeyType="go"
autoCapitalize="none"
autoCorrect={false}
secureTextEntry
onChangeText={this.handleChangePassword}
underlineColorAndroid="transparent"
onSubmitEditing={this.handlePressLogin}
/>
</Item>
</Form>
<View style={[Styles.loginRow]}>
<StyleProvider style={buttonTheme(commonColor)}>
<Button style={{ flex: 1, justifyContent: "center" }} full onPress={this.handlePressLogin}>
<NBText>Sign In</NBText>
</Button>
</StyleProvider>
</View>
<Text style={Styles.registerText} onPress={this.handlePressRegister}>
Tidak punya akun? Daftar di sini
</Text>
</View>
</ScrollView>
);
}
}
const mapStateToProps = state => {
return {
//fetching: state.login.fetching,
users: state.users
};
};
const mapDispatchToProps = dispatch => {
return {
//attemptLogin: (username, password) => dispatch(LoginActions.loginRequest(username, password)),
getUsers: () => dispatch(UsersActions => dispatch(UsersActions.getUsers()))
};
};
export default connect(mapStateToProps, mapDispatchToProps)(LoginScreen);
最佳答案
在您的 usersRedux.js 中定义您的用户类型。
其中之一是 UsersTypes.USERS_REQUEST。
在 sagas 的 index.js 中,您尝试在 UsersTypes.USER_REQUEST 上运行您的用户 saga。
此操作类型值不存在,您在 USERS_REQUEST 中缺少 S。
在这种情况下,您传递给 takeLatest 以开始您的传奇的 actionType 被称为模式。
关于javascript - 使用 API react Native Redux Ignite 错误 "uncaught at check",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49524159/
你好我是 Angular JS 的初学者,当我开始创建模块和 Controller 时,我无法打印我的消息,下面是我的代码 var myModule = angular.module("myFirst
我对 JQuery 还是个新手,我正在尝试使用它遍历 JSON 数组并使用数组中的数据更新我的网页。 JSON 文件如下所示: [ { "firstname":"John",
我正在使用 AngularJS 1.3.5,我正在尝试从 json 文件中获取信息。这是我的代码:HTML 文件: {{da
我正在创建 Bootstrap 模板。我收到两个错误,我不知道自己做错了什么。当我搜索类似的问题时,似乎是脚本错乱了,但我认为它们的位置是正确的。 两个错误: 未捕获的 ReferenceError:
我试图用子菜单制作导航栏,但我一直收到 dropMenu 未定义,当我将鼠标悬停在两个巴黎链接上时,我收到 Uncaught TypeError: Cannot read property 'styl
我正在尝试在名为 UserComponent 的 Angular 组件上运行 karma 测试。在此组件中,我有一个 ngOnInit 执行此操作: ngOnInit() { const
当我启用 login.spec.ts 测试时,对于不同的测试,我总是随机收到此错误。未捕获错误:未捕获( promise ):错误:无法匹配任何路由。 URL 段:“注销” 我尝试使用以下方法伪造 a
自从我设置一个与 Angular 一起运行的网络应用程序以来已经有一段时间了。我正在通过一个旧项目回顾我的步骤(尝试在我正在做的页面上实现一个 Controller ,确保 Controller 文件
在 AWS Elastic Beanstalk 上部署应用程序后会发生此错误。构建和部署成功,所有模块都正常工作,除了一个显示上述 super 表达式错误的模块。一切似乎都在本地机器上正常工作,甚至可
我刚刚开始使用 Node.js 并尝试使用模块。我已经安装了 Node 和 npm,并确保一切顺利。我将在下面添加代码来向您展示我得到了什么。 我有两个 js 文件,它们在这里。 app.js: va
在 Android 4.4.2 KitKat (API 19) 模拟器上运行时,我的代码出现问题... 当我在 Android 4.3 (API 18) 模拟器上模拟我的项目时,它正常工作并使用 Ma
function more(){ var MoreDetails = document.getElementById('MoreDetails'); More
我正在练习 Javascript,并且有以下代码,该代码在 sets[i][j] = initial_sets [i ][j]; 行。这个想法似乎是正确的,但我不明白为什么会出现错误。 var set
$(document).ready(function(){ $('#name').val('Name1'); }); function clickMe(){ console.lo
我正在创建一个网络应用程序,但我遇到了一个无法解决的简单问题。我已将产生问题的代码放在这里:http://jsfiddle.net/rkumarnirmal/5w3FG/ 应该显示此答案的第二个ale
我正在执行一项长时间运行的任务,在中间的某个位置,可能会抛出此异常: Uncaught DOMException: Blocked a frame with origin "http://localh
我试图通过使用 HTML5 中的 onEnded 属性一首接一首地播放 3 首歌曲。这是我的第一次尝试,但出现错误。 错误: Uncaught ReferenceError: src is not d
检查 Fiddle 以查看发生的故障。 当我将数据(即使我将其留空)添加到文本框并尝试单击“添加”时,它没有执行任何操作。 打开 Chrome 和 Firefox 控制台都给我同样的错误,它说“cha
这个问题在这里已经有了答案: How to access the correct `this` inside a callback (13 个回答) 关闭5年前。 您好,这是我的(快捷方式)示例代码:
我正在处理一个项目,每次 Node 运行我的代码时,浏览器控制台都会给我这个: Uncaught TypeError: Failed to resolve module specifier "expr
我是一名优秀的程序员,十分优秀!