我的结构如下:
Component 1
- |- Component 2
- - |- Component 4
- - - |- Component 5
Component 3
Run Code Online (Sandbox Code Playgroud)
组件3应该根据组件5的状态显示一些数据.由于props是不可变的,我不能简单地将它保存在组件1中并转发它,对吧?是的,我读过有关redux的内容,但不想使用它.我希望只有反应就可以解决它.我错了吗?
我收到以下错误
未捕获的TypeError:无法读取未定义的属性"setState"
甚至在构造函数中绑定delta之后.
class Counter extends React.Component {
constructor(props) {
super(props);
this.state = {
count : 1
};
this.delta.bind(this);
}
delta() {
this.setState({
count : this.state.count++
});
}
render() {
return (
<div>
<h1>{this.state.count}</h1>
<button onClick={this.delta}>+</button>
</div>
);
}
}
Run Code Online (Sandbox Code Playgroud) 我有
var TestApp = React.createClass({
getComponent: function(){
console.log(this.props);
},
render: function(){
return(
<div>
<ul>
<li onClick={this.getComponent}>Component 1</li>
</ul>
</div>
);
}
});
React.renderComponent(<TestApp />, document.body);
Run Code Online (Sandbox Code Playgroud)
我想为点击列表元素的背景着色.我怎么能在React中做到这一点?
就像是
$('li').on('click', function(){
$(this).css({'background-color': '#ccc'});
});
Run Code Online (Sandbox Code Playgroud) 这是我的代码.我想使用onClick事件获取对象和目标元素中的数据.谁能帮我.
handleClick = (data) => {
console.log(data);
}
<input type="checkbox" value={data.id} defaultChecked={false} onClick={this.handleClick.bind(null, data)}/>
Run Code Online (Sandbox Code Playgroud) 我想在警报窗口中显示此人的电子邮件.但是,我不知道如何将电子邮件作为参数传递给displayAlert方法.此外,它也不会让我使用.因此,我必须将displayAlert方法指定给变量并在onClick中使用它.我不知道为什么它不会让我直接调用它.
class People extends React.Component{
render (){
var handleClick = this.displayAlert;
var items = this.props.items.map(function(item) {
return(
<ul key = {item.id}>
<li>
<button onClick= {handleClick}>{item.lastName + ', ' + item.firstName}</button>
</li>
</ul>
)
});
return (<div>{items}</div>);
}
displayAlert (){
alert('Hi');
}
}
class PersonList extends React.Component{
render () {
return (
<div>
<People items={this.props.people}/> /* People is an array of people*/
</div>
);
}
}
Run Code Online (Sandbox Code Playgroud)假设我们有这样的组件
const Example = () => {
const [counter, setCounter] = useState(0);
const increment = () => setCounter(counter => counter + 1);
return (
<div>
<Button onClick={increment} />
<div>{counter}</div>
</div>
);
}
Run Code Online (Sandbox Code Playgroud)
当我将onClick处理程序作为箭头函数传递时,我eslint抛出一个警告:
error JSX props should not use arrow functions react/jsx-no-bind
Run Code Online (Sandbox Code Playgroud)
正如我从这篇文章的答案中读到的:https : //stackoverflow.com/questions/36677733/why-shouldnt-jsx-props-use-arrow-functions-or-bind# :~: text=Why%20you%20shouldn 't%20use,previous%20function%20is%20garbage%20collected。
简短的回答是因为每次都会重新创建箭头函数,这会损害性能。这篇文章提出的一个解决方案是用空数组包装在useCallback钩子中。当我改成这个时,eslint 警告就真的消失了。
const Example = () => {
const [counter, setCounter] = useState(0);
const increment = useCallback(() => setCounter(counter => counter + …Run Code Online (Sandbox Code Playgroud) 我正在尝试了解钩子功能,但是我似乎还不太清楚如何useCallback正确使用该函数。据我从有关钩子的规则了解到,我应该将它们称为顶级,而不是在逻辑(如循环)之内。这让我很困惑,应该如何useCallback在从循环渲染的组件上实现。
看一下下面的示例代码片段,其中我创建了5个带有onClick处理程序的按钮,该处理程序将按钮的编号打印到控制台。
const Example = (props) => {
const onClick = (key) => {
console.log("You clicked: ", key);
};
return(
<div>
{
_.times(5, (key) => {
return (
<button onClick={() => onClick(key)}>
{key}
</button>
);
})
}
</div>
);
};
console.log("hello there");
ReactDOM.render(<Example/>, document.getElementById('root'));Run Code Online (Sandbox Code Playgroud)
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.11/lodash.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id='root'>
</div>Run Code Online (Sandbox Code Playgroud)
现在,由于我在中使用arrow函数<button onClick={() => onClick(key)}>,因此每次在Example呈现时都会创建一个新的函数实例,这是因为我希望onClick函数知道哪个按钮调用了它。我以为可以通过使用来使用新的react hooks功能来防止这种情况useCallback,但是如果将其应用到上,const onClick则仍会为每个渲染创建一个新实例,这是因为需要给key参数提供内联箭头功能,并且不允许这样做据我所知将其应用于循环内的渲染(尤其是循环顺序是否可能会改变吗?)。
那么useCallback在保持相同功能的情况下,我将如何在这种情况下实施呢?有可能吗?
我刚刚学习了React Native,我想用动态数据创建一系列按钮.我目前的代码是:
var locations = this.state.campus.map(function(item, key){
return(
<TouchableHighlight key={key}
style={[styles.button, (this.state.location==={item} && styles.buttonPressed)]}
underlayColor='#dddddd'
onPress={()=>this.buttonPress({item})} >
<Text style={
styles.plainText}>{item}</Text>
</TouchableHighlight>
)
Run Code Online (Sandbox Code Playgroud)
我的问题在于线条
style={[styles.button, (this.state.location==={item} && styles.buttonPressed)]}
Run Code Online (Sandbox Code Playgroud)
和
onPress={()=>this.buttonPress({item})}
Run Code Online (Sandbox Code Playgroud)
我正在尝试使用地图函数动态生成这些行.如果我使用静态数据(即单独生成每个按钮),但这些代码行完美无缺,但使用动态数据失败.代码确实产生了一个显示,所以问题不在于渲染,问题在于功能.
按下按钮,我得到的错误信息未在对象中定义,而样式只会导致整个显示不呈现.
很明显,动态数据({item})在Text元素内部工作,但在作为数据传递给其他两个元素时则不起作用.我尝试使用{{item}}但这会引发语法错误.
有没有办法在React Native中处理这样的动态数据?
在 React Native 的 Formik 文档中,有一个示例表单:
<Formik initialValues={{ email: '' }} onSubmit={(values) => console.log(values)}>
{({ handleChange, handleBlur, handleSubmit, values }) => (
<View>
<TextInput onChangeText={handleChange('email')} onBlur={handleBlur('email')} value={values.email} />
<Button onPress={handleSubmit} title="Submit" />
</View>
)}
</Formik>
Run Code Online (Sandbox Code Playgroud)
然而,这给了我一个打字稿错误:
No overload matches this call.
Overload 1 of 2, '(props: Readonly<ButtonProps>): Button', gave the following error.
Type '(e?: FormEvent<HTMLFormElement> | undefined) => void' is not assignable to type '(ev: NativeSyntheticEvent<NativeTouchEvent>) => void'.
Types of parameters 'e' and 'ev' are incompatible.
Type 'NativeSyntheticEvent<NativeTouchEvent>' is not …Run Code Online (Sandbox Code Playgroud) 假设我在父组件中有一个函数,我想将其用作子组件的回调。哪种方式更好?
render() {
return (
<Child handleClick={this.handleClick.bind(this)} />
)
}
Run Code Online (Sandbox Code Playgroud)
或者
constructor() {
super();
this.handleClick = this.handleClick.bind(this);
}
Run Code Online (Sandbox Code Playgroud)
根据这个eslint,最好在构造函数中这样做,因为 render() 方法可能会被多次调用。这对我来说非常有意义。
然而,这仅仅意味着绑定函数最终成为每个实例的属性。从而违背了原型的全部目的。
我确实了解属性初始值设定项:
handleClick = () => {
// do stuff
}
Run Code Online (Sandbox Code Playgroud)
但看起来这个语法还远没有被 ES2017(或者无论下一个可能是什么)达成一致。出于这个原因,我害怕使用这种语法,因为它可能永远不会进入该语言。
那么,说了这么多,解决这个问题的最佳方法是什么?
编辑:具体来说,下面的AirBnb示例是否有一些细微差别,使其免受Ori Drori评论中的tslint规则/ SO线程的影响?
我正在使用tslint-react并遵循AirBnb的React风格指南
AirBnb的规则"使用箭头函数来关闭局部变量"显示了在纯无状态组件的返回(渲染)中使用的lambda函数.
function ItemList(props) {
return (
<ul>
{props.items.map((item, index) => (
<Item
key={item.key}
onClick={() => doSomethingWith(item.name, index)} // This ok??
/>
))}
</ul>
);
}
Run Code Online (Sandbox Code Playgroud)
tslint-react的规则"jsx-no-lambda"似乎说这是一件坏事.
jsx-no-lambda:在渲染调用堆栈中创建新的匿名函数(使用函数语法或ES2015箭头语法)可以对付纯组件渲染.在两个lambdas之间进行相等性检查时,React将始终将它们视为不相等的值,并强制组件重新渲染,而不是必要的.
我对这里的最佳做法感到困惑,AirBnb的风格指南是否具有免除关注的细微差别.
干杯!
我onClick在React组件中有一个包含以下内容的道具:
onClick={_.bind(this.callMe, this, argToPass)}
Run Code Online (Sandbox Code Playgroud)
请记住,这是在使用React.createClass的React组件中,因此组件函数应该绑定到它的上下文.
不幸的是,当我尝试通过执行以下操作来绑定它时:
onClick={this.callMe(argToPass)}
Run Code Online (Sandbox Code Playgroud)
它破坏了我的一项测试.
我不想绑定它,因为它像这样的道具传递:
onClick={this.callMe(argToPass).bind(this)}
Run Code Online (Sandbox Code Playgroud)
b/c性能问题.
什么是香草javascript相当于:
_.bind(this.callMe, this, argToPass)
Run Code Online (Sandbox Code Playgroud)
这将允许函数正确绑定.
谢谢!
reactjs ×12
javascript ×5
typescript ×2
bind ×1
dynamic ×1
ecmascript-6 ×1
formik ×1
jquery ×1
lambda ×1
lodash ×1
native ×1
react-hooks ×1
react-native ×1
tslint ×1
usecallback ×1