-
-
Notifications
You must be signed in to change notification settings - Fork 256
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
TypeError: 'set' on proxy: trap returned falsish for property '0' #205
Comments
Ah! I realized that I should modify the state instead of the snapshot. 🥲 Sorry about that! |
Well, it's actually good you reported. you voted up.
|
@dai-shi I get a similar error:
I'm using it with ink state.tsimport { proxy } from 'valtio'
class State {
title = ''
description = ''
setTitle(title: string) {
this.title = title
}
setDescription(description: string) {
this.description = description
}
}
export const state = proxy(new State()) ui.tsximport React from 'react'
import { useSnapshot } from 'valtio'
import { Box } from 'ink'
import Gradient from 'ink-gradient'
import BigText from 'ink-big-text'
import { state } from './state'
import { Input } from './components/Input'
interface IApp {}
const App = ({}: IApp) => {
const snap = useSnapshot(state)
return (
<Box flexDirection="column">
<Gradient name="fruit">
<BigText text="Compose New Post" font="tiny" />
</Gradient>
<Input
label="Title"
onChange={(title: string) => {
return title
}}
onSubmit={(title) => {
console.log('title', title)
snap.setTitle(title)
}}
/>
<Input
label="Description"
onChange={(description: string) => {
return description
}}
onSubmit={(description) => {
console.log('description', description)
snap.setDescription(description)
}}
/>
</Box>
)
}
module.exports = App
export default App Haven't found a solution for my problem though :( |
snap.setTitle(title) This is trying to set the title of the snapshot, which is not modifiable. state.setTitle(title) We have https://github.com/pmndrs/eslint-plugin-valtio to detect this. |
@dai-shi I tried it & it did give a warning in VSCode saying: Better to just use proxy state.eslint(valtio/state-snapshot-rule)
const snap: {
title: string;
description: string;
setTitle: (title: string) => void;
setDescription: (description: string) => void;
} So then I tried using snap.title = title instead of setTitle(title) And it still gives the same warning. I want to know how to fix it? All I want to do is store the state in Valtio of a simple string. |
@deadcoder0904 You need to do: state.title = title or state.setTitle(title) |
@dai-shi But why? Why wouldn't const snap = useSnapshot(state)
// snap.title = title
// or snap.setTitle(title) I can't understand why The docs are correctly using |
So, you can't modify snap. snap.title = 'foo' // doesn't work because snap is frozen. |
I am also kinda confused by this, how should this be correctly done @dai-shi ? store.ts export interface VStore {
categories: Category[];
loadCategories: () => void;
}
export const vstore = proxy<VStore>({
categories: [],
loadCategories // some method
}); Presentation UI const HomePage = () => {
const data = useSnapshot(vstore);
useEffect(() => {
const loadData = async () => {
await data.loadCategories();
};
loadData();
}, []);
return (
<>
{/* Some more components here */}
<CategorySlider categories={data.categories} />
</>
);
};
export default HomePage; CategorySlider Component const CategorySlider = ({
categories = []
}: CategorySliderProps) => {
const [categoryList, setCategoryList] = useState(categories);
useEffect(() => {
setCategoryList(categories);
}, [categories]);
const selectCategory = (name: string) => () => {
const newCategoryList = categoryList.map((category: Category) => {
category.selected = false; // I get an error here
if (category.name === name) {
category.selected = true;
}
return category;
});
setCategoryList(newCategoryList);
};
return (
<Slides>
{categoryList.map((category: Category, idx: number) => {
return (
<Slide key={idx}>
<CategoryCard
selected={category.selected}
onClick={selectCategory(category.name)}
/>
</Slide>
);
})}
</Slides>
);
};
export default CategorySlider; I still cannot modify the data even I passed it down as a prop and used |
@geocine const HomePage = () => {
const data = useSnapshot(vstore)
// ...
return (
<>
{/* Some more components here */}
<CategorySlider categories={data.categories} selectCategory={(idx, value) => { vstore.categories[idx].selected = value } />
</>
)
}
const CategorySlider = ({
categories,
selectCategory,
}: {
categories: Category[]
selectCateogry: (idx: number, value: boolean) => void
}) => {
// ...
} Also, this 👇 works fine, because useEffect is outside render. - await data.loadCategories();
+ await vstore.loadCategories(); |
Thanks @dai-shi your explanation is very clear to me. Your work made me realize I've been doing state mutations wrong all along. Now this makes me more aware because it actually prevents me from doing this kind of stuff. Really great work! This is very useful , as doing this , exhaustive deps on - await data.loadCategories();
+ await vstore.loadCategories(); |
I'm working with Three.js.
I've set up a store in a file out of all react components as
I then init the scene in the initialization code as
In a React component, I get a snapshot of the scene as
And try to add a new group to the scene when I click on a menu item as
This will cause an error shown as below:
where the scene.add() function has source code as below:
I know that I can use ref(scene) to get rid of the error, but I do want to track any changes that happen on the scene object.
The text was updated successfully, but these errors were encountered: