-
-
Notifications
You must be signed in to change notification settings - Fork 619
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Using react hooks with ink: Invariant Violation #108
Comments
The issue is Ink is getting pegged to a version of react-reconciler that doesn't support hooks yet. I was able to get it working by using yarn and adding these resolutions to my package.json: "resolutions": {
"react-reconciler": "0.18.0-alpha.2",
"scheduler": "0.12.0-alpha.3"
} Those alpha versions have the hooks code. Then you can import the hooks and use them. I converted the README: import React, { useState, useEffect } from 'react';
import { render, Color } from 'ink';
const Counter = () => {
const [i, setI] = useState(0);
useEffect(() => {
const timer = setInterval(() => setI(i + 1), 100);
return () => clearInterval(timer);
});
return <Color green>{i} tests passed</Color>;
};
render(<Counter />); |
Doesn't work for me, when I am doing yarn install it says Can you please share the complete package.json please? and .babelrc? |
Which version of react are you using? |
It looks like your "dependencies" field has a version of |
This is what I currently have, it installs fine but it still gives the invariant error after running it.
This is what comes out of the code you showed:
And the error:
|
This is what I had when it worked:
I know they published a new alpha version, so I don't know if that changes things, but it did work at the time. |
Oh, wait, you're using ink's |
I thought h pragma is required. What is the correct setup then? |
Ohhh my mistake, here's the issue: the current version of Ink is a custom implementation, so it's not tied to React in particular so much as it's inspired by it. The next version (2.0, as seen on the If you switch to the |
I tried with the latest alphas as the following: {
"dependencies": {
"ink": "2.0.0-10",
"react": "16.8.0-alpha.1",
"react-dom": "16.8.0-alpha.1"
},
"devDependencies": {
"@types/react": "^16.7.21",
},
"resolutions": {
"react-reconciler": "0.19.0-alpha.1",
"scheduler": "0.13.0-alpha.1"
}
} Keep in mind that you have to use Yarn in order for the import { render, Text } from 'ink';
import React, { useEffect, useState } from 'react';
const MyComponent = () => {
const [state, set] = useState(0);
useEffect(() => {
// Give it some time before updating to re-render with the new
// state later.
const id = setTimeout(() => {
set(1);
}, 250);
return () => {
clearTimeout(id);
};
});
return <Text>This {state}</Text>;
};
render(<MyComponent />); |
Thanks everyone for pitching in on this issue! If I'm not mistaken, release of React Hooks is around the corner and they should release stable versions of their packages, which I will be able to safely upgrade Ink to. Afterwards hooks will be usable with Ink. |
I have noticed that hooks doesn't quite work the way you're used to as in other environments. This is probably due to the nature of how the lifetime of a program works in command-line (or TTY). For example, I tried to port Without using useEffect(() => {
// Using resume will ask for user input and "pause" the program further and won't
// continue to render until that is done.
// process.stdin.resume();
process.stdin.on('keypress', handleKeyPress);
return () => {
process.stdin.removeListener('keypress', handleKeyPress);
};
}, []);
}; The The program will just run and exit, as there's nothing that tells it to stop and wait for user input before continuing. I also tried to use the Using Here's the code, using the const TextInput = ({
focus,
value,
placeholder,
onChange,
onSubmit
}) => {
const stdinContext = useContext(StdinContext);
function handleKeyPress(ch, key) {
if (!focus) {
return;
}
if (hasAnsi(key.sequence)) {
return;
}
if (key.name === 'return') {
if (onSubmit) {
onSubmit(value);
}
}
if (key.name === 'backspace') {
if (onChange) {
onChange(value.slice(0, -1));
}
return;
}
if (
key.name === 'space' ||
(key.sequence === ch && /^.*$/.test(ch) && !key.ctrl)
) {
if (onChange) {
onChange(value + ch);
}
}
}
useEffect(() => {
stdinContext.setRawMode(true);
stdinContext.stdin.on('keypress', handleKeyPress);
return () => {
stdinContext.setRawMode(false);
stdinContext.stdin.removeListener('keypress', handleKeyPress);
};
}, []);
const hasValue = value.length > 0;
return <Color dim={!hasValue}>{hasValue ? value : placeholder}</Color>;
}; |
So I just investigated the keypress event thing, and I got it sorted out by using |
Yeah, older versions of Current |
@Jessidhia I think this is related to Ink not implementing |
A very bare implementation would be It looks like this was a last-minute (good!) change in facebook/react#14757 |
Cool, I'm working on a CLI tool with Ink@next so I'll PR this upstream. Ink also would need to bump some dep versions to get it working with Hooks again. |
Now that hooks are officially released, I will look into how to make Ink work with them :) Thanks everyone for helpful input! And of course, if somebody's already solved this problem, PRs are always welcome! |
This should be fixed now ✌️ See #124 |
Hooks are working now thanks to @zkat! |
Hey,
I am trying to use the new react hooks with Ink components, but I get the error:
I am using the hooks inside a function component, so I guess it is related to Ink implementation?
Here is the code:
The text was updated successfully, but these errors were encountered: