Block editor giving invalid hook call error - reactjs

I am trying to get the wordpress block editor to load in a react project: https://www.npmjs.com/package/#wordpress/block-editor.
I have set it up exactly as per the example on the npm page but it gives an invalid hook error. I think perhaps it is due to a version mismatch as error suggest?
This is the code:
import {
BlockEditorProvider,
BlockList,
WritingFlow,
ObserveTyping
} from "#wordpress/block-editor";
import { SlotFillProvider, Popover } from "#wordpress/components";
import { useState } from "#wordpress/element";
import "#wordpress/components/build-style/style.css";
import "#wordpress/block-editor/build-style/style.css";
export default function MyEditorComponent() {
const [blocks, updateBlocks] = useState([]);
return (
<BlockEditorProvider
value={blocks}
onInput={(blocks) => updateBlocks(blocks)}
onChange={(blocks) => updateBlocks(blocks)}
>
<SlotFillProvider>
<Popover.Slot name="block-toolbar" />
<WritingFlow>
<ObserveTyping>
<BlockList />
</ObserveTyping>
</WritingFlow>
<Popover.Slot />
</SlotFillProvider>
</BlockEditorProvider>
);
}
And the typical hook error:
Error
Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See [link] for tips about how to debug and fix this problem.
I have setup a codepen to tyr it here: https://codesandbox.io/s/sleepy-proskuriakova-op59q
I looked up wordpress version of react and it seems to be 16.6.3 so set that in sandbox and used an older version of react scripts (2.1.8) that at the time was using 16.6.2 but no change in error. I tried several combinations of versions with no change.
What is actually causing this error? How can I get this component to load?

Here is a working codesandbox.
Things I've changed:
react and react-dom to 16.13.1 which is the version used in #wordpress/element
Had to add DropZoneProvider
Install #wordpress/block-library and call registerCoreBlocks
For more code examples you can check the official storybook docs, the source code is in the bottom panel, under the Story tab.

Related

React / Reactstrap Warning: Legacy context API has been detected within a strict-mode tree

This is brand new install - I have not put any transitions on the Alert component
To replicate the code it is simple
import React from "react";
import { Alert } from "reactstrap";
export const Index = () => {
return (
<div>
<Alert color='primary'>This is a primary alert — check it out!</Alert>
</div>
);
};
Error Msg: Please update the following components: Transition
How does one go about updating Transition or eliminating it all together?
In the event that someone comes here on after searching the question and is looking for insight this is it.
React strap (at the time of this post) uses the react-transition-group things fade in and out and menus slide up and down. After amalgamating the info on this subject here and on Github they are currently updating the library. I have finished the coding of that component by ignoring the warning.
It did not impede this iteration of that component. Happy Coding.
I have this same warning, and I fixed it changing in the index.js file, the value of <React.StrictMode> to <React.Fragment>.
Since this removes the warning, is not guaranteed that your can be bulletproof.
This issue was reported, and apparently fixed but I received the same error even with the updated source code. It's more than just the error as well - it can cause components to re-render
Here is one github thread from the reactstrap repo about this (but there are a number of them): https://github.com/reactstrap/reactstrap/issues/1340
There are a number of issues related to this warning though.
As best I can tell it has something to do with an item in Transition.js, and I think it may have to do with a this.context call when a component is 'entering'
But, the project I encountered this issue is the first React App I'm building, and I'm not quite ready to learn the Legacy Context API, so that's just my best guess and in the end I just opted for an alternative package.
I don't have the rep to put this in a comment, so the only answers I have are:
Report the issue to the reactstrap team and wait/assist with a fix
Use an alternative package

How to implement Error Boundary with React Hooks Component

How can we implement error Boundary in React Hooks. Is it even supported with react Hooks?
The questions is whether it is possible to implement Error Boundary as a hook and the answer is no BUT it does not mean that you can not use Error Boundary class components in a project which you use hooks heavily.
Create a Error Boundary class component and wrap your React Functional Components(hooks) with the Error Boundary class component.
You can implement error boundary in react hooks with the help of react-error-boundary package.
npm install --save react-error-boundary
Then:
import {ErrorBoundary} from 'react-error-boundary'
function ErrorFallback({error, resetErrorBoundary}) {
return (
<div role="alert">
<p>Something went wrong:</p>
<pre>{error.message}</pre>
<button onClick={resetErrorBoundary}>Try again</button>
</div>
)
}
const ui = (
<ErrorBoundary
FallbackComponent={ErrorFallback}
onReset={() => {
// reset the state of your app so the error doesn't happen again
}}
>
<ComponentThatMayError />
</ErrorBoundary>
)
Please read more on React-error-boundary
*There is no Error Boundaries in hook yet *
componentDidCatch
and
getDerivedStateFromError
There are no Hook equivalents for these methods yet, but they will be added soon.
I wrote react-use-error-boundary to achieve this.
React 16 introduced Error Boundaries. As of React 17, there still is not an equivalent hook for function components.
I liked the API implemented by Preact's useErrorBoundary and attempted to recreate a similar API. If you're interested in building this from scratch you can checkout the code on GitHub.
You can't do that with hooks. Hooks do not have an equivalent of componentDidCatch. See this section of the hook FAQ
getSnapshotBeforeUpdate, componentDidCatch and getDerivedStateFromError: There are no Hook equivalents for these methods yet, but they will be added soon.

Do you really need to import 'React' when creating hooks? (React-hooks)

I saw the examples where https://reactjs.org/docs/hooks-custom.html they always do:
import React, { useState, useEffect } from 'react';
But React is not really used in the file, do we really need it and why?
I asked this question because I am encountering an issue with eslint saying:
'React' is defined but never used no-unused-vars - And I'm on create-react-app 3.0.1 which eslint is already included - (and I'm not sure how to fix this - already tried this and also tried adding it on package.json eslintConfig but still nothing)
You will need React if you are rendering JSX.
To avoid that eslint warning, you should use react-in-jsx-scope rule from eslint-plugin-react.
In that rule, it also explains why you need React in the file, even if you don't use it (you think you don't use it, but if you render JSX, you do).
When using JSX, <a /> expands to React.createElement("a"). Therefore the React variable must be in scope.
If you are using the #jsx pragma this rule will check the designated variable and not the React one.
React 17 has a new JSX transform which no longer requires the import (also backported to new versions 16.14.0, 15.7.0, and 0.14.10). You can read more about it here:
https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html
// no import needed
const App = () => <div>hello!</div>
However, you still need to import to use hooks:
import { useState } from 'react'
const App = () => {
const [stuff, setStuff] = useState('stuff')
return <div>{stuff}</div>
}
The docs also link to a script to automatically update all of the files in a project to fix all of the imports. Personally, I was in the habit of just using the React.useWhatever form so I never needed to mess with the import statement, but using named imports can potentially reduce the final bundle size.
The docs say the named import is now the recommended way, so this is NOT recommended, but if you really want to keep the React import, you can set the below eslint rule to stop it from complaining. Note that this will continue to require it in all files.
"react/jsx-uses-react": "error"
From the React official docs:
Fundamentally, JSX just provides syntactic sugar for the
React.createElement(component, props, ...children) function. The JSX
code:
<MyButton color="blue" shadowSize={2}>Click Me</MyButton>
compiles
into:
React.createElement(MyButton, {color: 'blue', shadowSize: 2},'Click Me' )
You can also use the self-closing form of the tag if
there are no children. So:
<div className="sidebar" />
compiles into:
React.createElement('div', {className: 'sidebar'}, null )
https://reactjs.org/docs/jsx-in-depth.html
EDIT Hooks are also under the React namespace, React.useState ...etc

ReactTestUtils has been moved

I'm starting learning React and while I was doing some tests i noticed two warning messages:
Warning: ReactTestUtils has been moved to react-dom/test-utils. Update references to remove this warning.
Warning: Shallow renderer has been moved to react-test-renderer/shallow. Update references to remove this warning.
They don't prevent the tests from running nor from properly validating, but there is always this error.
By looking at the docs, I found this page, even after I included those lines they recommend, the warning message is still showing up.
I'm trying a very simple test to start with, this is my code:
import React from "react";
import toJson from "enzyme-to-json";
import { shallow } from "enzyme";
import { About } from "./About";
describe('Rendering test', () => {
const component = shallow(<About />);
const tree = toJson(component);
it('Should render the About component', () => {
expect(tree).toMatchSnapshot();
})
it('Should not contain an h2 element', () => {
expect( component.contains('h2') ).toBe(false);
})
})
What do I need to do in order to solve this warnings? I already updated all my packaged to the latest versions.
If you are using React 0.14 or React <15.5, in addition to enzyme, you will have to ensure that you also have the following npm modules installed if they were not already:
npm i --save-dev react-addons-test-utils react-dom
If you are using React >=15.5, in addition to enzyme, you will have to ensure that you also have the following npm modules installed if they were not already:
npm i --save-dev react-test-renderer react-dom
I think it's coming from using the shallow render function from enzyme, which has not been updated for v15.5 yet (there is a pull request for it though).
You can try to use one of the other render function (render or mount), but this will change the semantics of your test (and may or may not still produce the warning).
Your other option is to not use enzyme and use react-test-renderer/shallow yourself, but the enzyme API is quite nice for testing components.
My advice is to wait for the version of enzyme and just live with the warning for now.
Update August of 2017
If you install react-test-renderer it will work but all react-* versions should match:
e.g.
react#15.4.2
react-test-renderer#15.4.2
react-dom#15.4.2
react-addons-test-utils#15.4.2
In my environment, only this config worked!
I was still receiving the following warning after trying steps listed above.
Warning: ReactTestUtils has been moved to react-dom/test-utils. Update references to remove this warning.
Updating the path in \node_modules\react-addons-test-utils\index.js solved this for me.
Old:
lowPriorityWarning(
false,
'ReactTestUtils has been moved to react-dom/test-utils. ' +
'Update references to remove this warning.'
);
module.exports = require('react-dom/lib/ReactTestUtils');
New:
lowPriorityWarning(
false,
'ReactTestUtils has been moved to react-dom/test-utils. ' +
'Update references to remove this warning.'
);
module.exports = require('react-dom/test-utils');

Violation 'requestIdleCallbackHandler ' took ms

I'm writing an app generated with create-react-app with redux, react-redux, and react-router. Whenever I click a Link like this:
import React from 'react'
import { Link } from 'react-router'
import ThingCard from '../../components/ThingCard'
const ThingsList = ({things}) => {
return (
<ul>
{things.map(thing =>
<Link to={"/things/"+thing.id} key={thing.id}><ThingCard thing={thing}/></Link>
)}
</ul>
)
}
export default ThingsList
I see the following warnings in my console. I have no idea where they come from or what they mean. Google search didn't yield any useful results. Can these warnings be safely ignored, if not how can I find out more about them? I believe this issue is preventing the parent page from rendering it's children.
I've disabled all network requests.
EDIT: This error only shows up in Chrome Canary and not Google Chrome. However, Google Chrome is not rendering the children properly (potentially due to this issue)
It can be safely ignored. Here is good explanation why do you see this.
The reason you see requestIdleCallback here is most probably because you are using React 16+ which has a totally new architecture Fiber You can read more about it
TL;DR; It just notifies you that some of your/their code took longer than 16ms, thus you may not always get 60fp.

Resources