gpt4 book ai didi

reactjs - 如何通过 react-redux ,withRouter 在 react 中使用 refs?

转载 作者:行者123 更新时间:2023-12-03 13:31:45 27 4
gpt4 key购买 nike

我正在尝试在连接到 react-redux 的组件中使用 ref

我试过这个解决方案。
connect(null, null, null, {forwardRef: true})(myCom)<myCom ref={ref => this.myCom = ref} />
根据 react-redux 文档,这很好用,但是现在当我尝试使用
withRouter同时我收到一个错误:

Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?



所以我试过的最终导出代码导致了上述错误

export default connect(null, null, null, { forwardRef: true })(withRouter(withStyles(styles)(myCom)));

备注 :withStyles 不会引起任何问题,因为我尝试仅删除 withRouter,问题已解决。

有没有办法解决这个问题?

最佳答案

为了将引用传递给由 withRouter 包裹的组件你需要调用它wrappedComponentRef .我建议使用 withRouter作为最外层的包装器,因此您的示例如下所示:

withRouter(connect(null, null, null, {forwardRef: true})(myCom));
<myCom wrappedComponentRef={ref => this.myCom = ref} />

以下示例和描述改编自我的一个相关答案: Get ref from connected redux component withStyles

以下是来自 react-redux todo list tutorial 的修改版本的代码这显示了正确的语法。我在此处包含了我更改的两个文件(TodoList.js 和 TodoApp.js),但沙箱是一个完全有效的示例。

TodoApp ,我使用了 wrappedComponentRef 上的引用(通过 TodoList 属性)获取并显示其高度。显示的高度只有在 TodoApp 时才会更新重新渲染,所以我添加了一个按钮来触发重新渲染。如果在待办事项列表中添加几个待办事项,然后单击重新渲染按钮,您将看到列表的新高度显示出来(表明 ref 已完全工作)。

TodoList ,我正在使用 withStyles在待办事项列表周围添加蓝色边框以显示 withStyles正在工作,我正在显示主题的原色以显示 withTheme正在工作。我也在显示 location来自 withRouter 的对象证明 withRouter正在工作。
TodoList.js
import React from "react";
import { connect } from "react-redux";
import Todo from "./Todo";
import { getTodosByVisibilityFilter } from "../redux/selectors";
import { withStyles, withTheme } from "@material-ui/core/styles";
import clsx from "clsx";
import { withRouter } from "react-router-dom";

const styles = {
list: {
border: "1px solid blue"
}
};

const TodoList = React.forwardRef(
({ todos, theme, classes, location }, ref) => (
<>
<div>Location (from withRouter): {JSON.stringify(location)}</div>
<div>theme.palette.primary.main: {theme.palette.primary.main}</div>
<ul ref={ref} className={clsx("todo-list", classes.list)}>
{todos && todos.length
? todos.map((todo, index) => {
return <Todo key={`todo-${todo.id}`} todo={todo} />;
})
: "No todos, yay!"}
</ul>
</>
)
);

const mapStateToProps = state => {
const { visibilityFilter } = state;
const todos = getTodosByVisibilityFilter(state, visibilityFilter);
return { todos };
};
export default withRouter(
connect(
mapStateToProps,
null,
null,
{ forwardRef: true }
)(withTheme(withStyles(styles)(TodoList)))
);

TodoApp.js
import React from "react";
import AddTodo from "./components/AddTodo";
import TodoList from "./components/TodoList";
import VisibilityFilters from "./components/VisibilityFilters";
import "./styles.css";

export default function TodoApp() {
const [renderIndex, incrementRenderIndex] = React.useReducer(
prevRenderIndex => prevRenderIndex + 1,
0
);
const todoListRef = React.useRef();
const heightDisplayRef = React.useRef();
React.useEffect(() => {
if (todoListRef.current && heightDisplayRef.current) {
heightDisplayRef.current.innerHTML = ` (height: ${
todoListRef.current.offsetHeight
})`;
}
});
return (
<div className="todo-app">
<h1>
Todo List
<span ref={heightDisplayRef} />
</h1>
<AddTodo />
<TodoList wrappedComponentRef={todoListRef} />
<VisibilityFilters />
<button onClick={incrementRenderIndex}>
Trigger re-render of TodoApp
</button>
<div>Render Index: {renderIndex}</div>
</div>
);
}


Edit Todo App with Redux

关于reactjs - 如何通过 react-redux ,withRouter 在 react 中使用 refs?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57313306/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com