本文介绍了从连接的 redux 组件获取 ref withStyles的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我导出了一个工作组件:

导出默认连接(mapStateToProps,动作,null, { withRef: true, forwardRef: true })(withTheme()(withStyles(styles)(MainMenu)));

它的调用:

this.menuRef = connectedMenu.getWrappedInstance()}用户={用户}/>

我希望得到一个 MainMenu ref,但我一直得到 WithTheme 对象.

我也尝试过通过innerRef,但出现以下错误:

TypeError: connectedMenu.getWrappedInstance 不是函数类型错误:无法读取 null 的属性getWrappedInstance"

在这之前,我已经尝试过 React.createRef() 格式,但没有奏效.

我如何获得这个参考?

解决方案

假设您使用的是 Material-UI 的 v4,您的 withTheme 语法不正确.在 v4 中,第一组括号

I have this export of a working component:

export default connect(
    mapStateToProps, actions,
    null, { withRef: true, forwardRef: true }
  )(withTheme()(withStyles(styles)(MainMenu)));

And its call:

<MainMenu
  ref={(connectedMenu) => this.menuRef = connectedMenu.getWrappedInstance()}
  user={user}
/>

I've expected to get a MainMenu ref, but I keep getting WithTheme object instead.

I've also tried to get through innerRef, but got the following errors:

TypeError: connectedMenu.getWrappedInstance is not a function
TypeError: Cannot read property 'getWrappedInstance' of null

Before all of that I've tried that React.createRef() format, but it didn't worked.

How do I get this ref?

解决方案

Assuming you are using v4 of Material-UI, your syntax for withTheme is incorrect. In v4 the first set of parentheses was removed.

Instead of

withTheme()(YourComponent)

you should have

withTheme(YourComponent)

Below is code from a modified version of the react-redux todo list tutorial that shows the correct syntax. I've included here the two files that I changed (TodoList.js and TodoApp.js), but the sandbox is a fully working example.

In TodoApp, I use the ref on TodoList to get and display its height. The displayed height will only get updated if TodoApp re-renders, so I've included a button to trigger a re-render. If you add a couple todos to the todo list, and then click the re-render button, you will see that the new height of the list is displayed (showing that the ref is fully working).

In TodoList, I'm using withStyles to add a blue border around the todo list to show that withStyles is working, and I'm displaying the primary color from the theme to show that withTheme is working.

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";

const styles = {
  list: {
    border: "1px solid blue"
  }
};
const TodoList = React.forwardRef(({ todos, theme, classes }, ref) => (
  <>
    <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 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 ref={todoListRef} />
      <VisibilityFilters />
      <button onClick={incrementRenderIndex}>
        Trigger re-render of TodoApp
      </button>
      <div>Render Index: {renderIndex}</div>
    </div>
  );
}

这篇关于从连接的 redux 组件获取 ref withStyles的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-31 06:01