question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

wrappingComponent can't work well with useContext hooks

See original GitHub issue
// utils.ts
export enum Action {
  view = 'view',
  edit = 'edit',
  cancel = 'cancel',
  save = 'save',
}

export type ModeType = Action.view | Action.edit;

export const ModeContext = createContext(Action.view as ModeType);

// EditableItem.tsx
interface EditableItemProps extends ColProps {
  label: string;
  viewContent: any;
  children: ReactNode;
  className?: string;
  style?: CSSProperties;
  disabled?: boolean;
}

export function EditableItem(props: EditableItemProps) {
  const {
    label,
    viewContent = '暂无数据',
    className,
    style,
    children,
    disabled,
    span,
    ...restProps
  } = props;
  const mode = useContext(ModeContext);
  console.log('mode inner', mode);
  const defaultSpan = span ? { span } : { xs: 24, md: 12, lg: 8, xl: 6 };
  return (
    <Col {...defaultSpan} className={className} style={style} {...restProps}>
      <FormItem label={label}>
        {mode === Action.edit && !disabled ? children : viewContent}
      </FormItem>
    </Col>
  );
}

// EditableItem.test.tsx
function ModeContextProvider(props: any) {
  const { children, mode } = props;
  console.log('mode provider', mode);
  return <ModeContext.Provider value={mode}>{children}</ModeContext.Provider>;
}

it('should render string', () => {
  const viewContent = 'test content';
  const wrapper = shallow(
    <EditableItem label="test" viewContent={viewContent}>
      test children
    </EditableItem>,
    {
      wrappingComponent: ModeContextProvider,
      wrappingComponentProps: {
        mode: Action.view,
      },
    }
  );
  expect(wrapper.getElement()).toMatchSnapshot();
  const provider = wrapper.getWrappingComponent();
  provider.setProps({
    mode: Action.edit,
  });
  wrapper.update();
  expect(wrapper.getElement()).toMatchSnapshot();
});

Current behavior

// console
mode provider view
mode inner view
mode provider edit
mode inner view

Expected behavior

// console
mode provider view
mode inner view
mode provider edit
mode inner edit // not view

Your environment

node v10.14.2 npm v6.9.0

API

  • shallow
  • mount
  • render

Version

library version
enzyme ^3.10.0
react ^16.8.6
react-dom ^16.8.6
react-test-renderer ^16.8.6
adapter (below)

Adapter

  • enzyme-adapter-react-16
  • enzyme-adapter-react-16.3
  • enzyme-adapter-react-16.2
  • enzyme-adapter-react-16.1
  • enzyme-adapter-react-15
  • enzyme-adapter-react-15.4
  • enzyme-adapter-react-14
  • enzyme-adapter-react-13
  • enzyme-adapter-react-helper
  • others ( )

Issue Analytics

  • State:open
  • Created 4 years ago
  • Reactions:10
  • Comments:6 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
Tan90Qiancommented, Jun 27, 2019

why ReactSixteenAdapter.createRenderer() don’t call createRenderWrapper() in ReactSixteenAdapter.createShallowRenderer() just like ReactSixteenAdapter.createStringRenderer() ?

// enzyme-adapter-react-16/src/ReactSixteenAdapter.js
class ReactSixteenAdapter extends EnzymeAdapter {
  ...
  createStringRenderer(options) {
    if (has(options, 'suspenseFallback')) {
      throw new TypeError('`suspenseFallback` should not be specified in options of string renderer');
    }
    return {
      render(el, context) {
        if (options.context && (el.type.contextTypes || options.childContextTypes)) {
          const childContextTypes = {
            ...(el.type.contextTypes || {}),
            ...options.childContextTypes,
          };
          const ContextWrapper = createRenderWrapper(el, context, childContextTypes);
          return ReactDOMServer.renderToStaticMarkup(React.createElement(ContextWrapper));
        }
        return ReactDOMServer.renderToStaticMarkup(el);
      },
    };
  }

  // Provided a bag of options, return an `EnzymeRenderer`. Some options can be implementation
  // specific, like `attach` etc. for React, but not part of this interface explicitly.
  // eslint-disable-next-line class-methods-use-this
  createRenderer(options) {
    switch (options.mode) {
      case EnzymeAdapter.MODES.MOUNT: return this.createMountRenderer(options);
      case EnzymeAdapter.MODES.SHALLOW: return this.createShallowRenderer(options);
      case EnzymeAdapter.MODES.STRING: return this.createStringRenderer(options);
      default:
        throw new Error(`Enzyme Internal Error: Unrecognized mode: ${options.mode}`);
    }
  }
}
Read more comments on GitHub >

github_iconTop Results From Across the Web

React: Unable to use useContext hook - Stack Overflow
You can only use hooks in the body of a function component. You can't use them in a callback function. So move the...
Read more >
A better way of solving prop drilling in React apps
We start by importing a createContext Hook, which is used for creating a context, and a useContext Hook, which will extract the state...
Read more >
How To Share State Across React Components with Context
The useReducer Hook is a good fit since you'll need to update the most recent state on every action. Create a reducer function...
Read more >
How to Use Context API with Hooks While Avoiding Bottlenecks
A function to show and hide a spinner should be accessible from any component in the application. Let's start with a simple implementation...
Read more >
Testing Modern React with Enzyme Shallow - Cassey Lottman
... Enzyme to test a React component that relies on a useContext hook ... I do use React for work, and have a...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Hashnode Post

No results found