Redux-form Liform在“ Connect(Form(BaseForm))”的上下文或道具中找不到“商店”

时间:2019-06-11 20:02:31

标签: reactjs symfony redux store

我已经在这个问题上苦苦挣扎了一段时间,但我没有找到或不理解Internet上的解决方案,因为我是ReactJS的初学者。所以我在这里。

上下文

我尝试为使用symfony 3.4和React 16.8的服务器和客户端渲染开发应用程序。
为此,我使用了limenius/react-bundle进行链接。
我使用了以下示例中的大量代码:https://github.com/Limenius/symfony-react-sandbox
我在这里告诉我我使用了哪个版本的相关软件包:

composer.json

"php": ">=7.2.2",
// Webpack
"symfony/webpack-encore-bundle": "^1.6",
"symfony/webpack-encore-pack": "^1.0",
// Limenius
"limenius/liform-bundle": "^0.13.0",
"limenius/react-bundle": "^3.0",

package.json

"@babel/plugin-proposal-class-properties": "^7.4.4",
"@babel/preset-react": "^7.0.0",
"babel-polyfill": "^6.26.0",
"babel-preset-env": "^1.7.0",
"babel-preset-react": "^6.24.1",
"liform-react": "^0.9.0",
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-on-rails": "^11.3.0",
"react-redux": "^7.1.0",
"react-router-dom": "^5.0.1",
"redux": "^4.0.1",
"redux-form": "^8.2.3",
"redux-persist": "^5.10.0",
"redux-thunk": "^2.3.0",

问题

当我尝试在我的React应用程序中使用包<Liform/>中的组件liform-react时,出现以下错误:

Uncaught Invariant Violation: Could not find "store" in either the context or props of "Connect(Form(BaseForm))". Either wrap the root component in a <Provider>, or explicitly pass "store" as a prop to "Connect(Form(BaseForm))".
    at invariant (http://dev.dummyreact/build/js/app.js:3662:15)
    at new Connect (http://dev.dummyreact/build/js/app.js:12525:57)
    at constructClassInstance (http://dev.dummyreact/build/js/app.js:50422:18)
    at updateClassComponent (http://dev.dummyreact/build/js/app.js:53748:5)
    at beginWork (http://dev.dummyreact/build/js/app.js:54705:16)
    at performUnitOfWork (http://dev.dummyreact/build/js/app.js:58373:12)
    at workLoop (http://dev.dummyreact/build/js/app.js:58413:24)
    at HTMLUnknownElement.callCallback (http://dev.dummyreact/build/js/app.js:39210:14)
    at Object.invokeGuardedCallbackDev (http://dev.dummyreact/build/js/app.js:39260:16)
    at invokeGuardedCallback (http://dev.dummyreact/build/js/app.js:39317:31)
The above error occurred in the <Connect(Form(BaseForm))> component:
    in Connect(Form(BaseForm)) (created by ReduxForm)
    in ReduxForm (created by Liform)
    in Liform (created by App)
    in div (created by App)
    in App (created by ConnectFunction)
    in ConnectFunction
    in Provider

此错误发生在服务器端和客户端: enter image description here


代码

在我的应用中,唯一的实体名为Page,并具有à属性:name。 首先要做的是创建Symfony / Type

PageType.php

<?php
namespace Osef\AppBundle\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;

class PageType extends AbstractType {
    public function buildForm(FormBuilderInterface $builder, array $options) {
        $builder->add('name',TextType::class,[
            'label' => 'Name',
            'required' => true,
            'attr' => [
                'placeholder' => 'Some name'
            ],
            'liform' => [
                'description' => 'Description liform'
            ]]
        );
    }
}

然后,我使用$liform->transform()方法将表单提供给视图

DefaultController.php

<?php
namespace Osef\AppBundle\Controller;

use Limenius\Liform\Liform;
use Osef\AppBundle\Entity\Page;
use Osef\AppBundle\Form\Type\PageType;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class DefaultController extends Controller {

    public function indexAction(Liform $liform) {
        $page = new Page();
        $form = $this->createForm(PageType::class, $page);

        return $this->render("@OsefApp/index.html.twig", array(
            "schema" => $liform->transform($form)
        ));
    }
}

在我的树枝模板内部,我使用limenius树枝扩展名来调用我的react组件,这些组件由JS端的reactOnReacts注册。 另外,我将模式参数(来自PHP)提供给商店。

index.html.twig

<!DOCTYPE html>
<html lang="fr">
<head>
    <meta charset="UTF-8">
    <title>{% block title %}Welcome!{% endblock %}</title>
    {% block stylesheets %}
        {{ encore_entry_link_tags('css/app') }}
    {% endblock %}
</head>
<body>

    <div id="react-container">{% spaceless %}{{ redux_store('TestStore', {
            'schema': schema
        }) }}{{ react_component('TestApp') }}{% endspaceless %}</div>

    {% block javascripts %}
        {{ encore_entry_script_tags('js/app') }}
    {% endblock %}
</body>
</html>

这对PHP方面很有好处。现在让我们看一下React代码。
首先是向ReactOnRail注册我的组件,以使它们可以被视图(上面的代码)访问

registration.js

import ReactOnRails from "react-on-rails";
import TestApp from './test/TestApp';
import TestStore from './test/store/TestStore';

ReactOnRails.register({ TestApp }); // The application
ReactOnRails.registerStore({ TestStore }); // Redux store

然后,我开发了一家商店,该商店只处理一个变量:schema

TestStore.js

import { createStore, applyMiddleware, compose } from "redux";

import thunkMiddleware from "redux-thunk";
import reducers from "../reducer";
import { initialStates } from "../reducer";

export default function configureStore(props) {
    const { schema } = props;
    const { testState } = initialStates;

    const initialState = {
        testState: {
            ...testState,
            schema
        }
    };

    let composeEnhancers =
        (typeof window !== "undefined" &&
            window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__) ||
        compose;

    const store = createStore(
        reducers,
        initialState,
        composeEnhancers(applyMiddleware(thunkMiddleware))
    );
    return store;
}

商店使用了我的TestReducer和来自软件包redux-form的form reducer的组合

reducer / index.js

import testReducer from "./testReducer";
import { initialState as testState } from "./testReducer";
import { combineReducers } from "redux";
import { reducer as formReducer } from "redux-form";

export default combineReducers({
    testState: testReducer,
    form: formReducer
});

export const initialStates = {
    testState
};

TestReducer仅具有一个伪动作,并且schema的初始化为空。

testReducer.js

export const initialState = {
    schema: null
};

export default function testReducer(state = initialState, action) {
    switch (action.type) {
        case "CHANGED":
            return { ...state, schema: null };

        default:
            return state;
    }
}

最后,这是我的应用代码

App.js

import React from "react";
import { connect } from "react-redux";
import Liform from "liform-react";

const App = (props) => {

    const { schema } = props;
    console.log("The props are correctly mapped at the store : "+JSON.stringify(schema));

    const submit = () => console.log("submit")

    // The application throw a error at this call of <Liform>
    return (
        <div>
            <h1>Form :</h1>
            <Liform
                schema={schema}
                onSubmit={submit}
            />
        </div>
    )
};

export default connect(state => ({
    schema: state.testState.schema
}))(App);

在最后一个文件中,我们可以看到我将App组件连接到商店,并从props中检索了模式。
console.log()用来验证模式是否被正确注入(这意味着商店可以从此处连接)。

我在分支storeerror上创建了带有完成代码的存储库。 https://github.com/ghauray/dummyreact/tree/storeerror

注意:此仓库可通过http服务器运行,并执行以下操作

php composer.phar install
npm install 
// In separate consoles
npm run serverside-watch
npm run watch

最后

因此,如果您已经解决了该错误,或​​者在我的代码中看到一些错误,或者您有一些想法,请随时与我分享!!

0 个答案:

没有答案