我正在尝试用来自API的数据填写个人资料表单。 不幸的是,在这种情况下,redux-form不想与我合作。 由于某些原因,无论我做什么,字段都保持为空。
出于某些原因,设置固定值而不是从reducer传递的值效果很好。
也许是因为我在动作创建者内部对API调用使用了redux-promise? 我如何忍受它并摆脱它。 这是我的表单组件。
import React, { Component } from 'react';
import { reduxForm, Field } from 'redux-form';
import { connect } from 'react-redux';
import { fetchRoleList, fetchUserData } from '../actions';
class UserEdit extends Component {
componentWillMount() {
this.props.fetchRoleList();
this.props.fetchUserData();
}
handleEditProfileFormSubmit(formProps) {
console.log(formProps);
}
getRoleOptions(selected_id) {
if (!this.props.profile) {
return <option>No data</option>;
}
return this.props.profile.roles.map(role => {
return <option key={role.role_id} value={role.role_id}>{role.name}</option>;
});
}
renderField(props) {
const { input, placeholder, label, value, type, meta: { touched, error } } = props;
return (
<fieldset className={`form-group ${ (touched && error) ? 'has-error' : '' }`}>
<label>{label}</label>
<input className="form-control" {...input} type={type} placeholder={placeholder} />
{touched && error && <div className="error">{error}</div>}
</fieldset>
);
}
renderSelect({ input, placeholder, options, label, type, meta: { touched, error } }) {
return (
<fieldset className={`form-group ${ (touched && error) ? 'has-error' : '' }`}>
<label>{label}</label>
<select className="form-control" {...input}>
{options}
</select>
{touched && error && <div className="error">{error}</div>}
</fieldset>
);
}
render() {
const { handleSubmit } = this.props;
const user = this.props.profile.user;
return (
<div> {user ? user.email : ''}
<form onSubmit={handleSubmit(this.handleEditProfileFormSubmit.bind(this))}>
<Field name="email" label="Email:" component={this.renderField} type="text" placeholder="email@gmail.com" className="form-control"/>
<Field name="name" label="Name:" component={this.renderField} type="text" placeholder="John Doe" className="form-control"/>
<Field name="role" label="Role:" component={this.renderSelect} type="select" className="form-control" options={this.getRoleOptions()}/>
<button action="submit" className="btn btn-primary">Edit user</button>
<Field name="password" label="Password:" component={this.renderField} type="password" className="form-control"/>
<Field name="passwordConfirm" label="Confirm Password:" component={this.renderField} type="password" className="form-control"/>
{ this.props.errorMessage
&& <div className="alert alert-danger">
<strong>Oops!</strong> {this.props.errorMessage}
</div> }
<button action="submit" className="btn btn-primary">Sign up!</button>
</form>
</div>
);
}
}
let InitializeFromStateForm = reduxForm({
form: 'initializeFromState'
})(UserEdit);
InitializeFromStateForm = connect(
state => ({
profile: state.profile,
initialValues: state.profile.user
}),
{ fetchRoleList, fetchUserData }
)(InitializeFromStateForm);
export default InitializeFromStateForm;
我相信动作创建者也将很有用:
export function fetchUserData(user_id) {
user_id = user_id ? user_id : '';
const authorization = localStorage.getItem('token');
const request = axios.get(`${ROOT_URL}/user/${user_id}`, {
headers: { authorization }
});
return {
type: FETCH_USER,
payload: request
};
}
我试图在我的Twitter引导Web应用程序中运行ReactJS。 我在使用样式时遇到一些问题。
有这个div:
...
<div class="ui-progressbar-value ui-widget-header ui-corner-left" style="width: 80%;"/>
...
我正在编写一些动态进度条,并希望进行80%的更改(请看下面的**)。 这是我在JSX中编写的代码:
var Task = React.createClass({
render: function() {
return (
<li>
<a href="#">
<span className="header">
<span className="title">{this.props.type}</span>
<span className="percent">{this.props.children}%</span>
</span>
<div className="taskProgress progressSlim progressBlue" >
<div className="ui-progressbar-value ui-widget-header ui-corner-left"
**style="width"+{this.props.value} +"%;" />**
</div>
</a>
</li>
);
}
});
我阅读了一些有关嵌入式sytle的文档,但是该示例非常简单。
谢谢你的帮助。
通过使用:
style={{width : this.props.children}}
它工作正常,但只是想知道如何将其强制为%而不是px。
我有一个带有ES6编写的组件的React应用程序-通过Babel和Webpack进行了编译。
在某些地方,我想包含特定CSS文件和特定组件,如react webpack手册中所建议
但是,如果在任何组件文件中,我都需要静态CSS资产,例如:
webpack --config webpack.common.js
然后编译失败并显示错误:
SyntaxError: <PROJECT>/assets/css/style.css: Unexpected character '#' (3:0)
at Parser.pp.raise (<PROJECT>\node_modules\babel-core\lib\acorn\src\location.js:73:13)
at Parser.pp.getTokenFromCode (<PROJECT>\node_modules\babel-core\lib\acorn\src\tokenize.js:423:8)
at Parser.pp.readToken (<PROJECT>\node_modules\babel-core\lib\acorn\src\tokenize.js:106:15)
at Parser.<anonymous> (<PROJECT>\node_modules\babel-core\node_modules\acorn-jsx\inject.js:650:22)
at Parser.readToken (<PROJECT>\node_modules\babel-core\lib\acorn\plugins\flow.js:694:22)
at Parser.pp.nextToken (<PROJECT>\node_modules\babel-core\lib\acorn\src\tokenize.js:98:71)
at Object.parse (<PROJECT>\node_modules\babel-core\lib\acorn\src\index.js:105:5)
at exports.default (<PROJECT>\node_modules\babel-core\lib\babel\helpers\parse.js:47:19)
at File.parse (<PROJECT>\node_modules\babel-core\lib\babel\transformation\file\index.js:529:46)
at File.addCode (<PROJECT>\node_modules\babel-core\lib\babel\transformation\file\index.js:611:24)
看来,如果我尝试在Component文件中要求CSS文件,那么Babel加载程序会将其解释为另一个源,并尝试将CSS转换为Javascript。
这是预期的吗? 有没有一种方法可以实现-允许已转译的文件显式引用不会被转译的静态资产?
我为.js / jsx和CSS资产都指定了加载程序,如下所示:
module: {
loaders: [
{ test: /\.css$/, loader: "style-loader!css-loader" },
{ test: /\.(js|jsx)$/, exclude: /node_modules/, loader: 'babel'}
]
}
查看完整的webpack配置文件
详细信息如下:
webpack.common.js-我使用的基本Webpack配置,因此我可以在开发人员和生产人员之间共享属性。
Gruntfile.js-用于开发的Gruntfile。 如您所见,它需要上面的webpack配置并向其中添加一些开发属性。 这可能引起问题吗?
Html.jsx-我的HTML jsx组件,尝试导入/获取CSS。 这是一个同构应用程序(使用Fluxbile),因此需要使用实际的HTML作为呈现的组件。 在我的应用程序的任何部分中,使用此文件中显示的require语句,都会给出所描述的错误。
这似乎与咕unt有关。 如果我仅使用webpack --config webpack.common.js
进行编译,则不会出错。
简短的答案:这是节点运行时错误。 在同构应用程序中尝试在服务器上加载CSS并不是一个好主意。
我们的React Native Redux应用程序使用JWT令牌进行身份验证。 有许多动作需要这样的令牌,并且许多令牌是同时分发的,例如 应用加载时。
例如。
componentDidMount() {
dispath(loadProfile());
dispatch(loadAssets());
...
}
loadProfile
和loadAssets
都需要JWT。 我们将令牌保存在状态AsyncStorage
中。我的问题是如何处理令牌过期。
最初,我将使用中间件来处理令牌到期
// jwt-middleware.js
export function refreshJWTToken({ dispatch, getState }) {
return (next) => (action) => {
if (isExpired(getState().auth.token)) {
return dispatch(refreshToken())
.then(() => next(action))
.catch(e => console.log('error refreshing token', e));
}
return next(action);
};
}
我遇到的问题是loadProfile
和loadAssets
操作将同时刷新令牌,因为在分发它们时令牌将过期。 理想情况下,我想“暂停”需要身份验证的操作,直到刷新令牌为止。 有没有办法用中间件做到这一点?
如何使用React.DOM更改HTML document.body.style.backgroundColor = "green";
上的样式?
我尝试了这段代码,但无法正常工作:
var MyView = React.createClass({
render: function() {
return (
<div>
React.DOM.body.style.backgroundColor = "green";
Stuff goes here.
</div>
);
}
});
如果您从浏览器控制台执行此命令,它将起作用(但我需要在ReactJS代码中起作用):document.body.style.backgroundColor = "green";
另请参阅此问题以获取类似但不同的解决方案:使用ReactJS和React Router更改每条路线的页面背景颜色?
我常这样声明无状态组件:
const example: React.SFC<IExample> = ({propsType}) => ();
但是,现在不推荐使用SFC,也许Dan Abramov的这个Twitter帖子解释了原因。
SFC已过时,现在应该使用什么?
我在React中的嵌套循环做错了什么? 我已经在Google中搜索了信息,但没有找到合适的信息。 您能帮我找到我理解的错误吗?
从图中可以看出,我有一个变量中的数据。 而且效果很好。 但是,当我添加的不是此<tr>
的值时,会出现错误!
var TableBalls80 = React.createClass({
render:function(){
var rows = this.props.rows;
var columnId = 0, trKey = 0, divKey = 0, td1stKey = 0;
var td2ndKey = 100;
return(
<table className='table table-bordered bg-success'>
<thead>
<tr className='danger'>
{rows[0].row.map(function (element){
columnId++;
return (
<th colSpan="2" key={columnId}>{columnId}</th>);
})}
</tr>
</thead>
<tbody>
{rows.map(function (rowElement){
return (<tr key={trKey++}>
{rowElement.row.map(function(ball){
console.log('trKey:'+trKey+' td1stKey'+td1stKey+' ball.value:'+ball.value+' td2ndKey:'+td2ndKey+' ball.count:'+ball.count);
return(<div key={divKey++}>
<td className='info' key={td1stKey++}>{ball.value}</td><td key={td2ndKey++}>{ball.count}</td>
</div>);
})}
</tr>);
})}
</tbody>
</table>);
}
});
错误(取决于从另一个<tr>
添加的项目):
未捕获的错误:不断违反:findComponentRoot(...,.0.1.1.0.2.0.0.1。$ 0. $ 9. $ 109):>无法找到元素。 这可能意味着DOM发生了意外更改(例如,通过>浏览器进行了更改),通常是由于在使用表时忘记了n ......`。
刚开始使用React-Native时,我遇到了一些需要静态图像的麻烦。
到目前为止,这是我非常基本的代码:
'use strict';
var React = require('react-native');
var {
AppRegistry,
StyleSheet,
Text,
Image,
View,
} = React;
var buzz = React.createClass({
render: function() {
return (
<View style={styles.container}>
<Image source={require('image!bg')} style={styles.bg}>
<Text style={styles.welcome}>
Welcome to Buzz! iOS interface to
</Text>
<Text style={styles.welcomeHeader}>Charityware</Text>
</Image>
</View>
);
}
});
var styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'transparent'
},
welcomeHeader: {
fontWeight: '600',
fontFamily: 'Helvetica',
color: '#fff',
fontSize: 50,
alignSelf: 'center'
},
bg: {
width: 400,
height: 300,
alignSelf: 'auto',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
},
});
AppRegistry.registerComponent('buzz', () => buzz);
主要的麻烦领域是:
<Image source={require('image!bg')} style={styles.bg}>
<Text style={styles.welcome}>
Welcome to Buzz! iOS interface to
</Text>
<Text style={styles.welcomeHeader}>Charityware</Text>
</Image>
打包并运行应用程序时,出现渲染错误:
我了解您需要在xcode中添加图像作为图像集,以便require
调用找到该图像并为此添加了图像集:
...但无济于事。 有人有什么想法吗? 我已经阅读了文档,并且似乎正在按照规定的方式进行操作。 谢谢!
刚接触React并尝试循环对象属性,但是React抱怨对象不是有效的React子代,有人可以给我一些有关如何解决此问题的建议吗? 我添加了createFragment,但不确定是否需要执行此操作或应该采用哪种方法?
JS
var tifs = {1: 'Joe', 2: 'Jane'};
var tifOptions = Object.keys(tifs).forEach(function(key) {
return <option value={key}>{tifs[key]}</option>
});
渲染功能
render() {
const model = this.props.model;
let tifOptions = {};
if(model.get('tifs')) {
tifOptions = Object.keys(this.props.model.get('tifs')).forEach(function(key) {
return <option value={key}>{this.props.model.get('tifs')[key]}</option>
});
}
return (
<div class={cellClasses}>
<div class="grid__col-5 text--center grid__col--bleed">
<h5 class="flush text--uppercase">TIF</h5>
<select id="tif" name="tif" onChange={this.handleChange}>
{tifOptions}
</select>
</div>
</div>
);
}
控制台错误
If you meant to render a collection of children, use an array instead or wrap the object using createFragment(object)
我正在使用以下简单的导航代码
<Router>
<Switch>
<Route exact path='/dashboard' component={Dashboard} />
<Route path='/dashboard/accounts' component={AccountPage} />
</Switch>
</Router>
<NavLink exact to={'/dashboard'}
disabled={this.props.item.disabled}
activeClassName='active'>
<NavLink exact to={'/dashboard/accounts'}
disabled={this.props.item.disabled}
activeClassName='active'>
URL更改,但视图未更改。 但是,当我刷新页面或手动转到该URL时,它确实会更改。
我目前正在React中学习钩子概念,并试图理解以下示例。
import { useState } from 'react';
function Example() {
// Declare a new state variable, which we'll call "count"
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
上面的示例在处理程序函数参数本身上增加计数器。 如果我想在事件处理函数中修改计数值怎么办
考虑下面的例子
setCount = () => {
//how can I modify count value here. Not sure if I can use setState to modify its value
//also I want to modify other state values as well here. How can I do that
}
<button onClick={() => setCount()}>
Click me
</button>
我一直在使用React 16.7-alpha中的新钩子系统,并且当我正在处理的状态是对象或数组时陷入useEffect的无限循环中。
首先,我使用useState并使用一个空对象启动它,如下所示:
const [obj, setObj] = useState({});
然后,在useEffect中,我再次使用setObj将其设置为空对象。 作为第二个参数,我传递[obj],希望如果对象的内容没有更改,它也不会更新。 但是它一直在更新。 我猜是因为不管内容如何,这些总是不同的对象,这使React认为它不断变化?
useEffect(() => {
setIngredients({});
}, [ingredients]);
数组也是如此,但是作为原语,它不会像预期的那样卡在循环中。
使用这些新的挂钩,在检查天气内容是否已更改时,应该如何处理对象和数组?
示例代码:[https://github.com/d6u/example-redux-update-nested-props/blob/master/one-connect/index.js]
观看现场演示:[http://d6u.github.io/example-redux-update-nested-props/one-connect.html]
我有上述组件,Repo和RepoList。 我想更新第一个仓库的标签(第14行)。 所以我派出了UPDATE_TAG
动作。 在我实施connect
之前,调度大约需要200毫秒,这是可以预期的,因为我们浪费了很多时间来更改mapStateToProps
s,而这没有改变。
添加connect
后,调度大约需要30毫秒。 在生产构建React.js之后,更新仅花费约17ms。 这样会好很多,但是Chrome开发者控制台中的时间轴视图仍指示帧框架(大于16.6毫秒)。
想象一下,如果我们有许多这样的更新,或者connect
比当前更新更复杂,我们将无法维持60fps。
我的问题是,对于嵌套组件的props这样小的更新,是否有更有效和规范的方法来更新内容? 我还能使用Redux吗?
通过将每个connect
替换为可观察的内部减速器,我得到了一个解决方案。 就像是
// inside reducer when handling UPDATE_TAG action
// repos[0].tags of state is already replaced with a Rx.BehaviorSubject
get('repos[0].tags', state).onNext([{
id: 213,
text: 'Node.js'
}]);
然后,我使用[https://github.com/jayphelps/react-observable-subscribe]在Repo组件内订阅了它们的值。 即使使用React.js进行开发,每次调度也仅花费5毫秒。 但是我觉得这是Redux中的反模式。
我按照Dan Abramov的回答中的建议进行了规范化,并更新了连接组件
新的状态形状为:
{
repoIds: ['1', '2', '3', ...],
reposById: {
'1': {...},
'2': {...}
}
}
我在mapStateToProps
周围添加了connect
,以设置初始渲染的时间。
但是,性能比以前差(初始渲染和更新)。 (来源:[https://github.com/d6u/example-redux-update-nested-props/blob/master/repo-connect/index.js,]实时演示:[http://d6u.github.io /example-redux-update-nested-props/repo-connect.html)]
// With dev build
INITIAL: 520.208ms
DISPATCH: 40.782ms
// With prod build
INITIAL: 138.872ms
DISPATCH: 23.054ms
我认为每个connect
上的connect都有很多开销。
根据Dan更新后的答案,我们必须返回connect
的mapStateToProps
参数来返回函数。 您可以查看Dan的答案。 我还更新了演示。
下面,我的计算机上的性能要好得多。 只是为了好玩,我还在我所说的减速器方法中添加了副作用(来源,演示)(严重的是不使用它,仅用于实验)。
// in prod build (not average, very small sample)
// one connect at root
INITIAL: 83.789ms
DISPATCH: 17.332ms
// connect at every <Repo/>
INITIAL: 126.557ms
DISPATCH: 22.573ms
// connect at every <Repo/> with memorization
INITIAL: 125.115ms
DISPATCH: 9.784ms
// observables + side effect in reducers (don't use!)
INITIAL: 163.923ms
DISPATCH: 4.383ms
刚刚添加了基于“记忆中的联系”的虚拟化示例
INITIAL: 31.878ms
DISPATCH: 4.549ms
我已经用谷歌搜索了很多,但是我没有找到以下问题的明确答案:react-router中的hashHistory和browserHistory有什么区别?
我已经使用Webpack,Sass和CSS模块构建了一段时间的项目。 通常在我的require
文件中,我定义一个类似以下的类:
:local(.button) {
color: white;
}
在我的React组件中,使用require
方法,我需要以下样式:
render = () => {
const styles = require('./MyStyles.scss');
<div className={ styles.button } />
}
世界一切都很好。 一切正常。
现在,我阅读了CSS模块页面,发现像我的require
一样,没有包含任何选择器,此外,它们还导入了以下样式:
import styles from './MyStyles.scss';
我以为“哇,看起来好多了,更容易看到它的导入位置,等等。而且我不希望不使用require
,而默认使用本地内容。” 所以我尝试了一下,立即遇到了几个问题。
1)`从'./MyStyles.scss'导入样式;
因为我在我的React文件上使用ESLint,所以立即引发错误:require
没有默认的导出,通常这是有意义的,但是CSS模块页面指出:
从JS模块导入CSS模块时,它会导出一个对象,该对象具有从本地名称到全局名称的所有映射。
因此,我自然希望样式表的默认导出也成为他们引用的对象。
2)我尝试了require
这可以通过linting,但是require
日志为未定义。
3)如果我恢复到require
导入样式的方法,则未定义为:global
的内容均未定义。
作为参考,我的webpack加载器(我还包括Node-Neat和Node-Bourbon,这两个很棒的库):
{ test: /.(scss|css)$/, loader: 'style!css?sourceMap&localIdentName=[local]___[hash:base64:5]!resolve-url!sass?outputStyle=expanded&sourceMap&includePaths[]=' + encodeURIComponent(require('node-bourbon').includePaths) +
'&includePaths[]=' + encodeURIComponent(require('node-neat').includePaths[1]) + '&includePaths[]=' + path.resolve(__dirname, '..', 'src/client/') }
在所有这些之后,我的问题是:
1)当将CSS模块与Sass一起使用时,我是否只能使用require
或:global
?
2)由于我使用的是webpack,这是否也意味着我只能require
我的样式?
我的index.js中有以下代码段
class App extends Component {
render() {
return ( <div style = { styles.app } >
Welcome to React!
</div>
)
}
}
该代码有效,但是每次我保存(ctrl + s)visual studio格式的jsx时,就像这样:
class App extends Component {
render() {
return ( < div style = { styles.app } >
Welcome to React!
<
/div>
)
}
}
我该如何解决? 谢谢
这个问题已经在这里有了答案:
我在像这样的react应用程序中有一些JSX代码:
...
_renderSignOutLink() {
if (!this.props.currentUser) {
return false;
}
return (
<a href="#" onClick={::this._handleSignOutClick}><i className="fa fa-sign-out"/> Sign out</a>
);
...
在调用函数之前,双冒号::
是什么意思?
我一直在使用React,并希望在React中使用Polymer标签。 由于React只处理基本的DOM标签,因此React无法识别Polymer标签。 有没有办法将Polymer标签添加到React DOM库?
我有时看到人们在导出组件时将它们包装在withRouter
中:
import { withRouter } from 'react-router-dom';
class Foo extends React.Component {
// ...
}
export default withRouter(Foo);
这是做什么用的,什么时候应该使用?
在这里,我尝试将state.autocomplete
设置为'hello',然后进行打印,但状态似乎为空。 当我刚刚使用setState
更新状态时怎么办? data
设置为全局变量。
var data = {
populate_at: ['web_start', 'web_end'],
autocomplete_from: ['customer_name', 'customer_address']
};
var AutocompleteFromCheckboxes = React.createClass({
handleChange: function(e) {
this.setState( { autocomplete_from: 'event.target.value' } );
console.log('autocompleteFrom state: ', this.state.autocomplete_from);
// ^ => Uncaught TypeError: Cannot read property 'autocomplete_from' of null
return 1;
},
render: function() {
var autocompleteFrom = this.props.autocomplete_from.map(function(value) {
return (
<label for={value}>
<input type="checkbox" name={value} value="{value}"
onChange={this.handleChange.bind(this)}
ref="autocomplete-from"/>
{value}
</label>
);
}, this);
return (
<div className="autocomplete-from">
{autocompleteFrom}
</div>
);
}
});
var DynamicForm = React.createClass({
getInitialState: function() {
return {
name : null,
populate_at : null,
same_as : null,
autocomplete_from : "not set",
title : null
};
},
saveAndContinue: function(e) {
e.preventDefault();
var data = {
name : this.refs.name.getDOMNode().value,
};
console.log('data: ' + data.name);
},
render: function() {
return (
<AutocompleteFromCheckboxes
autocomplete_from={this.props.data.autocomplete_from} />
);
}
});
var mountpoint = document.getElementById('dynamic-form');
if ( mountpoint ) {
React.render(<DynamicForm data={data} />, mountpoint);
}
});