我正在使用TypeScript项目迁移React以使用钩子功能(React v16.7.0-alpha),但我无法弄清楚如何设置析构元素的类型.
这是一个例子:
interface IUser {
name: string;
}
...
const [user, setUser] = useState({name: 'Jon'});
Run Code Online (Sandbox Code Playgroud)
我想强制user变量为类型IUser.我唯一成功的试验是分两个阶段进行:打字,然后初始化:
let user: IUser;
let setUser: any;
[user, setUser] = useState({name: 'Jon'});
Run Code Online (Sandbox Code Playgroud)
但我确信有更好的方法.此外,setUser应该初始化为一个带有IUser输入的函数,并且不返回任何内容.
另外,值得注意的是,const [user, setUser] = useState({name: 'Jon'});没有任何初始化的使用工作正常,但我想利用TypeScript强制在init上进行类型检查,特别是如果它依赖于一些道具.
谢谢你的帮助.
最近我正在阅读 react-redux 文档https://react-redux.js.org/next/api/hooks 并且有一个与平等比较和更新相关的部分,它说:
多次调用 useSelector(),每次调用返回一个字段值。
第一种方法:
const { open, importId, importProgress } = useSelector((importApp) => importApp.productsImport);
Run Code Online (Sandbox Code Playgroud)
第二种方法:
const open = useSelector((importApp) => importApp.productsImport.open);
const importId = useSelector((importApp) => importApp.productsImport.importId );
const importProgress = useSelector((importApp) => importApp.productsImport.importProgress);
Run Code Online (Sandbox Code Playgroud)
那么有什么真正的区别吗?或者由于破坏 useSelector 钩子会在检查引用时遇到麻烦?
有一些数据来自每 5 秒的长轮询,我希望我的组件在每次数组的一项(或数组长度本身)发生变化时分派一个动作。在将数组作为依赖项传递给 useEffect 时,如何防止 useEffect 进入无限循环,但如果任何值发生更改,仍然设法调度某些操作?
useEffect(() => {
console.log(outcomes)
}, [outcomes])
Run Code Online (Sandbox Code Playgroud)
其中outcomes是一组 ID,例如[123, 234, 3212]. 数组中的项目可能会被替换或删除,因此数组的总长度可能 - 但不必 - 保持不变,因此outcomes.length作为依赖传递不是这种情况。
outcomes 来自 reselect 的自定义选择器:
const getOutcomes = createSelector(
someData,
data => data.map(({ outcomeId }) => outcomeId)
)
Run Code Online (Sandbox Code Playgroud)
我是 reactJS 的新手,正在编写代码,以便在从 DB 加载数据之前,它会显示加载消息,然后在加载后,使用加载的数据渲染组件。为此,我同时使用了 useState 钩子和 useEffect 钩子。这是代码:
问题是,当我检查 console.log 时,useEffect 被触发了两次。因此,代码两次查询相同的数据,这是应该避免的。
下面是我写的代码:
import React from 'react';
import './App.css';
import {useState,useEffect} from 'react';
import Postspreview from '../components/Postspreview'
const indexarray=[]; //The array to which the fetched data will be pushed
function Home() {
const [isLoading,setLoad]=useState(true);
useEffect(()=>{
/*
Query logic to query from DB and push to indexarray
*/
setLoad(false); // To indicate that the loading is complete
})
},[]);
if (isLoading===true){
console.log("Loading");
return <div>This is loading...</div>
}
else {
console.log("Loaded!"); …Run Code Online (Sandbox Code Playgroud) 最近,我在同事的 React 代码中看到了一些将 setter 函数传递到钩子依赖数组的示例,这对我来说看起来不太正确。例如:
const MyComponent = () => {
const [loading, setLoading] = useState(true);
useEffect(() => {
doSomeBigLongNetworkRequest();
setLoading(false);
}, [setLoading, /* other deps */]);
// ...
}
Run Code Online (Sandbox Code Playgroud)
我的感觉是他们误解了依赖数组的目的,据我理解,依赖数组是为了指示要监视哪些状态,以便钩子在它们更改时可以再次触发,而不是简单地指示钩子需要使用该setLoading功能。由于该setLoading函数实际上从未改变,因此将其包含在依赖项中不会执行任何操作。
我是否正确,或者将设置器包含在数组中是否有意义?我的另一个想法是,也许这只是一个 linter 错误,因为 linter 无法识别该函数是 setter,并认为它可能会改变。
我还应该补充一点,在我见过的实例中,它们包含了 setter,但不包含变量。因此,在上面的示例中,setLoading,但不是loading将在依赖项数组中,并且钩子实际上不需要 的值loading。
是否可以检测元素引用何时改变其高度?我尝试使用以下内容,但是当元素的高度由于某种原因发生变化时,不会检测到该变化。(请考虑这也必须在 IE11 中工作)
useEffect(() => {
// detect change in reference height
}, [elementRef])
Run Code Online (Sandbox Code Playgroud) 一旦我运行下面的代码,我就会收到以下错误:
React Hook useEffect 缺少依赖项:'list'。包括它或删除依赖数组 react-hooks/exhaustive-deps
我找不到警告的原因。
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import Form from './Form';
const App = () => {
const [term, setTerm] = useState('pizza');
const [list, setList] = useState([]);
const submitSearch = e => {
e.preventDefault();
setTerm(e.target.elements.receiptName.value);
};
useEffect(() => {
(async term => {
const api_url = 'https://www.food2fork.com/api';
const api_key = '<MY API KEY>';
const response = await axios.get(
`${api_url}/search?key=${api_key}&q=${term}&count=5`
);
setList(response.data.recipes);
console.log(list);
})(term);
}, [term]);
return (
<div …Run Code Online (Sandbox Code Playgroud) 我有一个道具从父组件传递到子组件,该组件根据用户的输入而变化。
当子组件渲染之前该 prop 发生变化时,我想在子组件中触发数据获取。我该怎么做?
我通过使用尝试了以下方式useEffects(()=>{},[props.a, props.b]),但总是在渲染后调用。请帮忙!
import React, { useEffect, useState } from "react";
import "./styles.css";
export default function parentComponent() {
const [inputs, setInputs] = useState({ a: "", b: "" });
return (
<>
<input
value={inputs.a}
onChange={(event) => {
const value = event.target.value;
setInputs((prevState) => {
return { ...prevState, a: value };
});
}}
/>
<input
value={inputs.b}
onChange={(event) => {
const value = event.target.value;
setInputs((prevState) => {
return { ...prevState, b: value };
});
}}
/>
<ChildComponent a={inputs.a} …Run Code Online (Sandbox Code Playgroud) 我正在使用带有 antd 的 react hook 组件。为表设置列时,渲染函数给我一个 ESLint 错误:
ESLint:组件定义缺少 displayName (react/display-name)
我试过将 displayName 添加到对象中,但这不起作用。
这是代码:
const columns_payment_summary_table = [
{
title: FooConstants.LABEL_QUANTITY_SELECTED,
dataIndex: 'group',
key: 'group',
render: text => (
<span>{getCountForCountry(text)}</span>
),
}
]
Run Code Online (Sandbox Code Playgroud)
任何人都可以帮忙吗?
这是完整的组件代码(只是相关位)
import * as FooConstants from './constants'
import {connect} from 'react-redux'
import React, {useState, useEffect} from 'react'
import {Card, Table} from 'antd'
import PropTypes from 'prop-types'
const propTypes = {
foos: PropTypes.object.isRequired,
}
function Foos(props) {
const [selectedFooRows, setSelectedFooRows] = useState([])
useEffect(() => { …Run Code Online (Sandbox Code Playgroud) 我正在阅读有关功能更新的React Hook 文档并查看此引用:
“+”和“-”按钮使用函数形式,因为更新的值是基于之前的值
但是我看不出需要功能更新的目的是什么,它们与直接使用旧状态计算新状态有什么区别。
为什么 React useState Hook 的更新器函数根本需要函数式更新表单? 我们可以清楚地看到差异的示例有哪些(因此使用直接更新会导致错误)?
例如,如果我从文档中更改此示例
function Counter({initialCount}) {
const [count, setCount] = useState(initialCount);
return (
<>
Count: {count}
<button onClick={() => setCount(initialCount)}>Reset</button>
<button onClick={() => setCount(prevCount => prevCount + 1)}>+</button>
<button onClick={() => setCount(prevCount => prevCount - 1)}>-</button>
</>
);
}
Run Code Online (Sandbox Code Playgroud)
count直接更新:
function Counter({initialCount}) {
const [count, setCount] = useState(initialCount);
return (
<>
Count: {count}
<button onClick={() => setCount(initialCount)}>Reset</button>
<button onClick={() => setCount(count + 1)}>+</button>
<button onClick={() => setCount(count - …Run Code Online (Sandbox Code Playgroud) react-hooks ×10
reactjs ×10
javascript ×3
antd ×1
frontend ×1
react-redux ×1
typescript ×1
use-effect ×1