Reputation: 5765
Being a big fan of Storybook I like to test my components in Isolation.
Especially Forms.
However, I'm having a very hard time figuring out how the heck I can get my forms or even a single form field to work in isolation. (without Edit, Create, Resource and Admin wrapping everything).
What I basically want is just to render a SimpleForm component with a single Input inside to prototype each of my inputs. (I use custom inputs as I don't like Material-ui)
My inputs are decorated with addField from ra-core
like this textInput example:
import React from 'react';
import { addField } from 'react-admin';
import sanitizeRestProps from './sanitizeRestProps';
import { Input } from 'antd';
import Labeled from './Labeled';
const TextInput = ({ id, label, labelPosition, input, isRequired, ...rest }) => (
<Labeled label={label} position={labelPosition} id={id} isRequired={isRequired}>
<Input id={id} {...input} {...sanitizeRestProps(rest)} />
</Labeled>
);
export default addField(TextInput);
If I try to render this Input on it's own I get the error "Field must be inside a component decorated with reduxForm()"
Which is fair... I want to test that it "works" as well when I'm building it in a component, so I added a SimpleForm wrapper.
Like so:
return (
<SimpleForm>
<TextInput label={label} source="test" />
</SimpleForm>
);
The component now renders, but I can't edit it at all. The "onChange" function from the input
prop that it gets through SimpleForm and addField decorator does get called. But the value never changes.
I then tried to mock every prop this SimpleForm requires like this:
return (
<SimpleForm
resource="test"
record={{ id: 1, test: 'blah' }}
initialValues={{ test: 'test2' }}
save={console.log}
basePath="/test"
saving={false}
submitOnEnter={false}
undoable={false}
validate={() => true}
version={1}
>
<TextInput label={label} source="test" />
</SimpleForm>
);
But my input is still just empty, I can't edit it, and it doesn't get the initialValue or default value I set in the record...
It seems ridicolous if this REALLY needs a Resource, Edit and Admin components JUST to render a single form field.
Note (it's not my field that's broken) When I load up the full site where IT IS integrated with all the Admin, Resources, Edit, Create etc. These fields work just fine.
But it's a massive pain having to load the website, login, navigate etc. EVERYTIME I'm making small changes to a single Input component.
How can I mock that environment so I can test forms in isolation???
I'm using react-admin 2.8.5 (before they switched to react-final-form)'
Upvotes: 5
Views: 2337
Reputation: 927
Edit: Simply wrap the SimpleForm with a react-redux Provider with the store that react-admin and redux-form components expects. Tested with 2.8.5
import React from "react";
import { render } from "react-dom";
import { SimpleForm, TextInput } from "react-admin";
import { Provider } from "react-redux";
import { createStore, combineReducers } from "redux";
import { reducer as formReducer } from "redux-form";
const reducers = {
admin: (state = {}) => state,
form: formReducer
};
const store = createStore(combineReducers(reducers));
const App = () => (
<Provider store={store}>
<SimpleForm record={{ test: "test2" }}>
<TextInput label="label" source="test" />
</SimpleForm>
</Provider>
);
render(<App />, document.getElementById("root"));
Test it here:
https://codesandbox.io/s/react-final-form-submission-errors-example-jfd5k?file=/index.js:0-647
Old answer:
The minimal setup i find that works is this, it will display no layout, and will redirect directly to the input:
import { Admin, Resource, Layout, SimpleForm, TextInput } from 'react-admin'
const NoLayout = props => (
<Layout
appBar={"span"}
sideBar={"span"}
menu={"span"}
{...props}
/>
)
const Dashboard = props => (
<SimpleForm>
<TextInput source="test" label="Source Name"}/>
</SimpleForm>
)
const App = () => {
return (
<Admin dataProvider={() => {}} menu={"span"} dashboard={Dashboard} layout={NoLayout}>
<Resource name="test"/>
</Admin>
)
}
You don't need a real dataProvider. The Resource is for react admin not complaining about an empty Admin
Upvotes: 2