我正在使用 ReactHooks。我正在尝试访问功能中ref的User组件useEffect。但是我得到了elRef.current价值null,虽然我elRef.current作为第二个参数传递给useEffect. 但我想得到对div元素的引用。但在 之外(函数体)useEffect,ref值是可用的。这是为什么 ?我怎样才能得到elRef.current里面的价值useEffect?
代码
import React, { Component, useState, useRef, useEffect } from "react";
const useFetch = url => {
const [data, setData] = useState(null);
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState(null);
useEffect(
() => {
setIsLoading(true);
fetch(url)
.then(response => {
if (!response.ok) throw Error(response.statusText);
return response.json();
})
.then(json => { …Run Code Online (Sandbox Code Playgroud) 更新的问题:
如果我在滚动之前在输入字段中输入某些内容,则expanded道具将设置为 true - 正确
如果我向下滚动 - 展开设置为 false - 正确
如果我现在在输入字段中输入expanded内容仍然是false- 我希望再次expanded设置为true。
代码:
export default () => {
const [expanded, setExpanded] = useState(true)
let searchInput = React.createRef()
let scrollTopValue = 0;
function handleSearchInput() {
console.log(Boolean(searchInput.current.value.length))
setExpanded(Boolean(searchInput.current.value.length)) // first time true, don't get re triggered
}
useEffect(() => {
window.addEventListener('scroll', handleScroll)
return () => window.removeEventListener('scroll', handleScroll)
}, []);
function handleScroll() {
setExpanded(scrollTopValue > document.documentElement.scrollTop)
scrollTopValue = document.documentElement.scrollTop
}
return ( …Run Code Online (Sandbox Code Playgroud) 我正在建造一个 <BasicForm>组件,用于在我的应用程序中构建表单。它应该处理提交、验证并且还应该跟踪输入状态(如触摸、脏等)。
因此,它需要一些函数来完成所有这些,我一直想知道放置这些声明的最佳位置是什么(关于代码组织和性能优化,考虑 React 和 JavaScript 最佳实践)。
我正在使用 React 16.8 钩子并与 Webpack 捆绑。
到目前为止,这是我所拥有的:
基本表单.js
/* I moved those validating functions to a different file
because I thought they are helpers and not directly related
to my BasicForm functionality */
import { validateText, validatePassword, validateEmail } from './Parts/ValidationHelpers';
function BasicForm(props) {
const [inputs, setInputs] = useState({});
const [isSubmitting, setIsSubmitting] = useState(false);
// These are functions to handle these events
function onChange(event) {...}
function onBlur(event) {...}
function onFocus(event) {...}
// …Run Code Online (Sandbox Code Playgroud) 我正在使用带有钩子的 react-redux,我需要一个选择器,它采用的参数不是 prop。该文件指出
选择器函数不接收 ownProps 参数。但是,可以通过闭包(参见下面的示例)或使用柯里化选择器来使用 props。
但是,他们没有提供示例。如文档中所述,咖喱的正确方法是什么?
这就是我所做的,它似乎有效,但这是对的吗?从函数返回函数是否有影响useSelector(它似乎永远不会重新渲染?)
// selectors
export const getTodoById = state => id => {
let t = state.todo.byId[id];
// add display name to todo object
return { ...t, display: getFancyDisplayName(t) };
};
const getFancyDisplayName = t => `${t.id}: ${t.title}`;
// example component
const TodoComponent = () => {
// get id from react-router in URL
const id = match.params.id && decodeURIComponent(match.params.id);
const todo = useSelector(getTodoById)(id);
return <span>todo.display</span>;
}
Run Code Online (Sandbox Code Playgroud) 我即将开始一个使用 React-Redux 的项目。对于 API 参考,有 Hooks 和 connect()。因为,钩子是连接 API 的替代品。使用钩子或连接到我的 React-Redux 项目有什么区别。
使用 Hooks/Functional 组件在 React 中优化和使代码更具可读性的更好方法是什么?每个组件有一个 setState 钩子还是多个?
为了扩展我的问题,请考虑以下内容:
使用钩子,我们可以使用多个状态,以某种方式更方便地拆分特定用途的状态(例如,一种状态用于用户数据,另一种用于保存加载标志,另一种用于为 API 检索的数据等) . 在我的第一步中,我确信最好的方法是每个我想要管理的数据都有多个状态……但是,一段时间后,当我想要时,我开始遇到多个状态之间的同步问题更新/读取效果函数中的多个状态(useEffect)。
所以,我开始相信使用 Hooks 管理状态的最佳方法它只有一个使用对象的状态并从这里管理我的所有数据......就像类组件......
const [data, setData] = useState({
retrieveData: false,
apiData: [],
userInfo: [],
showModal: false
})
// To update:
setData(oldData => {
return { ...oldData, showModal: true }
})
// Or:
setData({ ...data, retrieveData: true })
Run Code Online (Sandbox Code Playgroud)
在我看来,最好有一个状态,但这可能会以某种我没有考虑的方式影响性能/可读性?
每次我在 data prop 中获取新数据但组件在我调用之前不会重新渲染 handlePanelSelection()
function StepPanel({ data, getTranslations }) {
const [panelsData, changePanel] = useState(data);
function handlePanelSelection(panelId) {
switch (panelId) {
case 8:
changePanel(getTranslations.NeeSubCategory);
break;
default:
changePanel(data);
break;
}
}
return (
<>
{panelsData.map(details => {
const imgsrc = requireContext('./' + details.image);
return (
<div key={details.id} className="block-list">
<div className="left-block">
<img src={imgsrc} alt="" />
</div>
<div className="right-block">
<h3>{details.title}</h3>
<p>{details.description}</p>
<label htmlFor="radio1" className="radio-btn">
<input
type="radio"
onClick={() => handlePanelSelection(details.id)}
name="radio1"
/>
<span></span>
</label>
</div>
</div>
);
})}
</>
);
}
Run Code Online (Sandbox Code Playgroud)
但是当我像下面一样取下钩子时它就起作用了
function …Run Code Online (Sandbox Code Playgroud) 根据有关 TypeScript 此类错误的其他类似问题(关于问题#44147937和#40796374),我发现分配null创建状态或引用会导致此问题:
Property ... does not exist on type 'never'
如何在这个示例组件中处理这个问题?
const FooComponent: FunctionComponent<FooInterface> = () => {
const myRef = useRef(null)
const handleClickOnButton = () => myRef?.current?.click();
return (
<div>
<div ref={myRef} />
<button onClick={handleClickOnButton} />
</div>
}
Run Code Online (Sandbox Code Playgroud) 从 API 获取新闻标题并每页显示 10 条新闻及其 ID。同样是 10 秒刷新,新的头条新闻出现。TableHead 映射内容看起来不错,但 tableBody 提供了此错误:
输入“字符串|” 日期”不可分配给类型“ReactNode”
//Init post
export interface InitPost {
title: string;
url: string;
created_at: Date;
author: string;
}
//state of post
const [posts, setPosts] = useState<InitPost[]>([]);
//colums
const columns: readonly Column[] = [
{ id: "title", label: "Title", minWidth: 170 },
{ id: "url", label: "URL", minWidth: 150 },
{ id: "created_at", label: "Created At", minWidth: 100 },
{ id: "author", label: "Author", minWidth: 100 },
];
Run Code Online (Sandbox Code Playgroud)
桌头部分: 精细
<TableHead> …Run Code Online (Sandbox Code Playgroud) 我正在使用 React Router 并且有两条路由呈现相同的组件:
<Switch>
<Route path="/aaa" component={Cmp} />
<Route path="/bbb" component={Cmp} />
</Switch>
Run Code Online (Sandbox Code Playgroud)
这是 Cmp 实现:
class Cmp extends Component {
componentWillUnmount() {
console.log('******************* UNMOUNTED');
}
render() {
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
正如我所料,在/aaa和之间导航/bbb并不会卸载 Cmp。
我正在使用钩子,所以我重写了组件:
function Cmp() {
useEffect(() => {
return () => {
console.log('******************* UNMOUNTED');
};
});
return null;
}
Run Code Online (Sandbox Code Playgroud)
而且很奇怪的是,在运行应用程序时,之间导航/aaa和/bbb执行console.log是CMP已卸载。
知道如何使用函数组件和钩子防止不必要的卸载吗?
react-hooks ×10
reactjs ×10
javascript ×5
react-redux ×2
typescript ×2
react-router ×1
redux ×1