我正在将React与TypeScript一起使用,并且想利用SELECT
category,
sum(sales_volume),
sum(return_volume),
sum(return_volume) / sum(sales_volume) as return_rate
FROM sales
GROUP BY 1;
钩子。
我想做这样的事情
创建第一个useEffect
来监听一些可观察到的rxJ,这将为我的组件设置内部状态的一个特定属性(此位起作用)
然后,我想听听组件内部状态变化的特定属性,当其变化时,我想在第二个useEffect
中做点什么(这很可能称为redux派生操作)
这是初始状态
useEffect
这部分有效
const initialState = {
isopen: false,
selectedNodeText : ''
}
但是我想添加第二个const Home: React.FunctionComponent<HomeProps> = (props) => {
const [currentState, setState] = useState(initialState);
useEffect(() => {
const sub = props.eventMessager.observe()
.pipe(
filter((event: IMessage) => event instanceof ShowInfoInSidePanel),
map((event: IMessage) => event as ShowInfoInSidePanel)
)
.subscribe(x => {
setState({ ...currentState, isopen: true, selectedNodeText: x.itemClicked });
});
return () => {
sub.unsubscribe();
}
}, []);
}
,我将状态的特定属性传递给我,所以这就是我所拥有的
useEffect
但是我收到此错误
但是所有将useEffect(() => {
//TODO : make a async redux thunk call to get the data
}, [currentState.selectedNodeText]);
与TypeScript一起使用的示例都可以满足我的要求。我该怎么做才能将useEffect
转换为string[]
,以使ReadOnlyArray<any>
开心?
答案 0 :(得分:0)
好的,这可能是一个虚拟的示例,但是这里的想法是,仅当currentState.selectedNodeText更改时,才获得console.log输出,而状态的其他部分更改时,则不会获得:
import * as React from "react";
import "./styles.css";
interface IState {
isopen: boolean;
selectedNodeText: string;
}
const initialState: IState = {
isopen: false,
selectedNodeText: ""
};
interface CardProps {
Title: string;
Image: string;
Body: string;
}
export const Card: React.FC<CardProps> = ({ Title }) => {
const [currentState, setCurrentState] = React.useState<IState>(initialState);
React.useEffect(() => {
console.log("Changed");
}, [currentState.selectedNodeText]);
const handleClick = () => {
setCurrentState({
...currentState,
isopen: true,
selectedNodeText: `${Math.random()}`
});
};
const handleChangeIsOpen = () => {
setCurrentState(prev => ({
...prev,
isopen: !prev.isopen
}));
};
return (
<div className="card">
<div className="title">{Title}</div>
<div className="body">{`IsOpen ${currentState.isopen} with text ${
currentState.selectedNodeText
}`}</div>
<button onClick={handleClick}>Change Selected Node Text</button>
<button onClick={handleChangeIsOpen}>Change isOpen</button>
</div>
);
};
export default function App() {
return (
<div className="App">
<Card Title="CardTitle" Image="Image" Body="Body" />
</div>
);
}
答案 1 :(得分:0)
您的结果中有一个依赖问题,不确定打字稿是否会注意到,但带有react-hooks的附加功能会告诉您有关情况。您可以尝试将回调传递给状态设置器,以便currentState不是依赖项。
道具。 eventMessager仍将是一个依赖项,因此请确保在父级重新渲染时不要更改此传递的prop的引用,因为如果这样做,它将每次都取消订阅和订阅。
const Home: React.FunctionComponent<HomeProps> = (props) => {
const [currentState, setState] = useState(initialState);
useEffect(() => {
const sub = props.eventMessager.observe()
.pipe(
filter((event: IMessage) => event instanceof ShowInfoInSidePanel),
map((event: IMessage) => event as ShowInfoInSidePanel)
)
.subscribe(x => {
//pass callback to setState to prevent currentState
// being a dependency
setState(
(currentState)=>({
...currentState,
isopen: true,
selectedNodeText: x.itemClicked
})
);
});
return () => {
sub.unsubscribe();
}
}, [props.eventMessager]); //add props.eventMessager as dependency
}
您收到的另一个错误可能是因为传入了您没有使用的依赖项,请尝试以下操作:
useEffect(
() => console.log(currentState.selectedNodeText),//using the dependency
[currentState.selectedNodeText]
);