Uniforms: Support for react 16.3 new context api?

Created on 7 Apr 2018  Â·  29Comments  Â·  Source: vazco/uniforms


Support for react 16.3 new context api?

enhancement

Most helpful comment

A lot of time (and failed attempts) later you can see an initial but fully working version on branch new-context.

All 29 comments

Hi @jy4618272. I guess you meant a support for it, right? If so, yes, I'm looking into it. I'd rather make it backwards compatible, so it probably won't happen soon. I can assure you, that if React 17 will come up, without the old context API, it'll be supported.

@radekmie is there any reason why people won't upgrade to React 16.3 ?

Yes, there is - backward compatibility. When that issue was created, React 16.3 was a bit over a week old and I wasn't sure about how to make it backwards compatible. Now, _some_ time later, I have an idea but haven't got time to implement it yet. As an upgrade to Babel@7 is quite ready (#443), I'll get to it soon.

OK, I've spent some time thinking about it and it won't be easy. Most probably, it'll be a very breaking change. Here are a few ideas along with descriptions.

<Form>
  <Provider>    // Rendered by Form.
    <BaseField> // Problem: no Consumer.
<Form>
  <Provider>      // Rendered by Form.
    <Consumer>    // Problem: who renders that?
      <BaseField>
<Form>
  <Provider>             // Rendered by Form.
    <BaseFieldContainer>
      <Consumer>         // Rendered by BaseFieldContainer.
        <BaseField>

Only the third option is applicable, but it'll break all components created with extend BaseField. It's also making the component tree more complex.


There's also a completely different idea, in align with the new API.

// This name is definitely not final.
import getFieldProps from 'uniforms/getFieldProps';

const Field = props =>
    <Consumer>
        {uniforms => {
            const next = getFieldProps(uniforms, props);

            return (
                <Provider value={next.context}>
                    {props.children(next.props)}
                </Provider>
            );
        }}
    </Consumer>
;

// Explicit.
const ExampleTextField = props =>
    <Field {...props}>
        {props => <input onChange={props.onChange} value={props.value} />}
    </Field>
;

// With HoC.
const ExampleText = props => <input onChange={props.onChange} value={props.value} />};
const ExampleTextField = connectField(ExampleText);

It makes the transition easier, as connectField works as before. There's no need for BaseField anymore. I'm not sure it'll work, especially with the whole lifecycle, as reset or default values, but it's an idea.

extends BaseField breaking is ok. React always discouraged extending components especially since they deprecated mixins. wrapBaseField(FieldComponent) is the way to go in my opinion and even if this turns out to be a breaking change for people extending BaseField I think it's worth it. Roll-out version 2.

@radekmie https://github.com/SmallStoneSK/react-new-context-hoc how about use HOC like this?

@jy4618272 this API is not a problem and of course, it’s possible.

React 16.6.0 introduces _old_ API in the new API. I have to check that, as this might be the best solution.

React 16.7.0-alpha.0 introduces hooks api. Perhaps this could be even better and less verbose way to share state between form and fields, wdyt?

Yep, it's also an idea. I'm just still thinking about the possibilities of non-breaking changes.

Using new context api without ponyfill is already a breaking change, isnt it?

Without - definitely.

After fiddling with it for a long while (4 attempts so far): it won't work without breaking the compatibility. Even with the new API, it still changes from this.context.uniforms to this.context. I think using hooks is the way to go, but I'm still a bit skeptic, as it's still a fresh (but duh, hyped so much) technology. Yep, it'll be a breaking change, so... A major version change. A big change.

Seems like you can just wait for React hooks and useContext to make this change fairly simple

I've also thought that, but hooks are still not helping, as there's no possibility to consume and provide the context in one level, as it is right now. You can use useContext to consume it _in-place_ (like the contextType or older contextTypes) but <Provider /> is still needed (but it wasn't; uniforms are using childContextTypes along with getChildContext, which is on the same instance).

A lot of time (and failed attempts) later you can see an initial but fully working version on branch new-context.

will u merge it into master?

@wittech Definitely not _very_ soon. I'm still testing it a lot and rethinking the API a little, as such a big and breaking change will definitely require a next major version.

When do you think you will be at a point to do a alpha release?

Or asked in another way: How would we go about using the new context api branch to give you feedback?

@gerwinbrunner I'm not sure about the data. Currently, I'm focused on docs and some minor fixes and this is next in line. Probably somewhere in august, but I cannot guarantee anything.

You can test it locally. A not-very-convenient-but-it-works method is to simply clone the repo, run npm i and then npm link packages into your project.

Oh that sounds awesome - So I’ll be happy to test when you are ready :)

On 29.07.2019, at 09:27, Radosław Miernik notifications@github.com wrote:

@gerwinbrunner https://github.com/gerwinbrunner I'm not sure about the data. Currently, I'm focused on docs and some minor fixes and this is next in line. Probably somewhere in august, but I cannot guarantee anything.

You can test it locally. A non-very-convinient-but-it-works method is to simply clone the repo, run npm i and then npm link packages into your project.

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub https://github.com/vazco/uniforms/issues/405?email_source=notifications&email_token=AAASN3S6NVTMAVCXWJIQ4VDQB2LU5A5CNFSM4EZLYMZKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD272WMI#issuecomment-515877681, or mute the thread https://github.com/notifications/unsubscribe-auth/AAASN3SOTTMKM5W3XJPRDALQB2LU5ANCNFSM4EZLYMZA.

@radekmie i find some very serious performance issue , the AutoForm will render every filelds twice .

logs like this:
QuickForm getNativeFormProps
AutoField.js:19 uniforms-antd AutoField render :firstName
AutoField.js:19 uniforms-antd AutoField render :lastName
AutoField.js:19 uniforms-antd AutoField render :workExperience
QuickForm.js:22 QuickForm getNativeFormProps
AutoField.js:19 uniforms-antd AutoField render :firstName
AutoField.js:19 uniforms-antd AutoField render :lastName
AutoField.js:19 uniforms-antd AutoField render :workExperience

if there are hundreds of fields , it's really a problem. is there any solution?

@wittech You've encountered it on the new-context branch, current version or both?

@radekmie both

@radekmie any idea about this?

It’s most probably caused by the mechanism of handling initial values. I’ll take a look into that.

@radekmie hi,i find https://github.com/alibaba/uform use a new way(rxjs) to solve this kind of issue. maybe it's a good idea.

Nope, they don’t have such a problem. It’s because uniforms delay the default value initialization, so if you won’t render a field, it won’t calculate its value. This makes the whole logic more schema-independent. Anyway, I’ll take a look into that.

It's already finished in v3. See #646 for more details.

Was this page helpful?
0 / 5 - 0 ratings