Пользовательский макет в компоненте SimpleForm в react-admin

Я хочу создать собственный макет сетки из двух столбцов в моем проекте response-admin на страницах Edit и Show. Я хочу отображать поля выбора и область загрузки изображений в левом столбце, а текстовые поля - в правом столбце, используя только один <SimpleForm>.

Просто так

Если я использую компонент div или <Card> в составе компонентов <SimpleForm> и <EditController>, я получаю сообщение об ошибке.

Warning: React does not recognize the `basePath` prop on a DOM element. 
If you intentionally want it to appear in the DOM as a custom 
attribute, spell it as lowercase `basepath` instead. If you 
accidentally passed it from a parent component, remove it from the DOM 
element.

Есть ли способ создать макет без этой ошибки?

Было бы полезно сначала посмотреть, как у вас дела, чтобы мы могли понять, откуда взялась ошибка.

Arturo Ribes 17.12.2018 13:04

Связанная проблема GitHub для response-admin: github.com/marmelab/react-admin/issues/…

William 15.11.2019 18:31
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
6
3
6 784
3

Ответы 3

Я решил это с помощью создания другого компонента с использованием div, <Grid/> и т. д. И использовал этот компонент в компоненте <SimpleForm>.

import {withStyles} from '@material-ui/core/styles';
import React from 'react';
import {
    EditController,
    SimpleForm,
    TextInput,
    SelectInput,
    Title,
} from 'react-admin';
import Grid from '@material-ui/core/Grid';
import Card from '@material-ui/core/Card';
import Poster from "../customField/Poster";
import {EditToolbar} from '../toolbar/CustomToolbar'
import {EditActions} from '../toolbar/CustomActions'

const editStyles = {
    root: {display: 'flex', alignItems: 'flex-start', width: '100%'},
    form: {flexGrow: 9},
};


class CardEdit extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            refresh: false
        };
    }

    render() {
        const FormDiv = withStyles(editStyles)(({children, classes, ...props}) => {
                return (
                    <div className = {classes.root}>
                        <div className = {classes.form}>
                            <Grid container spacing = {24}>
                                <Grid item xs = {6}>
                                    <TextInput source = "name" fullWidth />
                                </Grid>
                                <Grid item xs = {6}>
                                    <TextInput source = "card_id" fullWidth />
                                </Grid>
                            </Grid>
                        </div>
                        </div>
                )
            }
        )

        return (
        <EditController {...this.props}>
            {({resource, record, redirect, save, basePath, version}) => {
                return (
                <div>
                    <Title defaultTitle = "sample"/>
                    <Card>
                        <div style = {{ margin: '20px 20px 0 0' }}>
                            <EditActions
                                basePath = {basePath}
                                resource = {resource}
                                data = {record}
                                hasShow
                                hasList
                            />
                        </div>
                        {record && (
                            <SimpleForm
                                basePath = {basePath}
                                redirect = {redirect}
                                resource = {resource}
                                record = {record}
                                save = {save}
                                version = {version}
                                toolbar = {<EditToolbar/>}
                            >

                                <FormDiv record = {record} />
                            </SimpleForm>
                        )}
                    </Card>
                </div>
            )
            }}
        </EditController>
        )
    }
}

export default withStyles(editStyles)(CardEdit);

Не могли бы вы опубликовать код о том, как вы это сделали? Меня это тоже интересует.

Arturo Ribes 17.12.2018 13:03

@GreenMagic Я отредактировал свой комментарий, добавив код моей страницы редактирования, чтобы вы могли ссылаться на него.

selens 20.12.2018 02:57

На самом деле, это можно было бы сделать немного проще, если вам не нужны какие-либо пользовательские стили и тому подобное. Чтобы избавиться от ошибки basePath, просто продезинфицируйте реквизиты, переданные в компонент Material UI Grid:

const SanitizedGrid = ({basePath, ...props}) => {
  return (
    <Grid {...props} />
  );
};

Затем используйте его вместо обычной сетки:

export default props => (
  <SimpleForm {...props}>
    <SanitizedGrid container spacing = {16}>
        <Grid item xs>
            <TextInput source = "name" />
        </Grid>
    </SanitizedGrid>
  </SimpleForm>
);

Если это не было очевидно на первый взгляд, ключевым моментом здесь является то, что вы отделяете «basePath» от других «свойств» при определении «SanitizedGrid». Таким образом, когда вы передаете {... props} компоненту Grid, basePath не появляется.

William 15.11.2019 18:32

В качестве другого способа я только что разработал (благодаря ответу Александра) хороший общий способ добавления любого настраиваемого HTML-содержимого в форму реакции-администратора:

import React, { Fragment }      from 'react';
import { SimpleForm }           from 'react-admin';

const CustomContent = ({ basePath, record, resource, children }) => (
  <Fragment>
    {children}
  </Fragment>
);

export const MyForm = (props) => (
  <SimpleForm>
    <CustomContent>
      <h3>Custom Content</h3>
      <p>I can now add standard HTML to my react admin forms!</p>
    </customContent>
  </SimpleForm>
);

Вы получаете опору basePath (которая, вероятно, вам не нужна), но реквизиты записи и ресурса могут быть полезны для вашего пользовательского контента (если вы переключите код на использование опоры рендеринга)

Другие вопросы по теме