Git Product home page Git Product logo

Comments (13)

gaperton avatar gaperton commented on July 29, 2024 1

Btw. With my recent changes, you can shorten this:

    const jointLink = Link.value( linked.info.value, x => {
      linked.info.set( x );
      infoLink.set( x);
    });

to this:

    const jointLink = linked.info.onChange( x => infoLink.set( x ) );

Thank you for your input. Hope you'll enjoy the library. Let me know if there will be some other problems.

from nestedlink.

gaperton avatar gaperton commented on July 29, 2024

Really weird. Let me clarify, please.

This one

<input value={ linked.info.value } onChange={ infoLink.action( setValue ) }/>

Is the one you lose focus on? Or the second one?

It looks suspicious, btw. You're taking the value from one place, but writing user's input to different place. Shouldn't it look like this?

const jointLink = Link.value( linked.info.value, x => {
    linked.info.set( x );
    infoLink.set( x );
});

...

<Input valueLink={ jointLink } />

Here we construct ad-hoc link wrapper around linked.info, which keeps infoLink in sync when set with a value.

from nestedlink.

gaperton avatar gaperton commented on July 29, 2024

Does this Link.value help? I can add link.onChange( ) hooks to make this stuff simpler. So, it will look just like:

linked.info.onChange( x => infoLink.set( x ) );

from nestedlink.

gaperton avatar gaperton commented on July 29, 2024

Nice idea, will do it anyway. Just let me know if it helps for your case.

from nestedlink.

gaperton avatar gaperton commented on July 29, 2024

Another note. Standard <input> will not support valueLink prop in the next React version, and sometimes it behaves weird.

Try to use Input component from tags.jsx instead, and check if it will help.

import { Input } from 'valuelink/tags'

tags.jsx is also the perfect place for your custom form controls styling, if you copy it over to your project.

from nestedlink.

peletiah avatar peletiah commented on July 29, 2024

Ah, the jointLink-example is a lot simpler! But it does not fix the focus-issue. But I investigated a bit more in the meantime and I guess the problem are changing keys on every re-render. I'm using this in combination with react-anything-sortable.

linkToObject.map() breaks the behaviour of my Sortable-component and I need to add a dynamic key to it to get Items to be sortable again. This dynamic key is probably the cause for the focus-issue. I'll post some example-code in my next comment, just want to get out this information while I have your attention.

Thanks for pointing out the upper-case Input, I didn't see the difference between the examples and my code and was wondering why I'd still get the depreciation-warning :-)

from nestedlink.

gaperton avatar gaperton commented on July 29, 2024

Okay. npm update, and now you can do just linked.info.onChange( x => infoLink.set( x ) ).

from nestedlink.

gaperton avatar gaperton commented on July 29, 2024

Yes, changing keys in the lists will cause React to recreate inputs. To fix that you probably need to add some permanent ids to you objects which you're sorting when you create objects, if you don't have them yet.

{
    _id : _.uniqueId( 'x' ),
   ...
}

or just

let _count = 0;
...
{
    _id : _count++
    ...
}

Then, use this item._id as key.

from nestedlink.

gaperton avatar gaperton commented on July 29, 2024

Example would be good, since problem seems to be tricky.

from nestedlink.

peletiah avatar peletiah commented on July 29, 2024

Give me a few more minutes...

from nestedlink.

gaperton avatar gaperton commented on July 29, 2024

Okay. Meanwhile, the docs for new link.onChange and link.pipe. I changed API a bit, as previous implementation introduced memory leak due to the fact that links are cached, and loosing validation error.

So, that's final API (1.3.10). Seems to works fine.

const jointLink = linked.info.onChange( x => infoLink.set( x ) )

https://github.com/Volicon/NestedLink/#-linkonchange-callback--any--void---link

from nestedlink.

peletiah avatar peletiah commented on July 29, 2024

Ok, it took me a while to reproduce the error with a simplified example, here's the example-code where the sorting works but the focus issue is present (Due to an ever-changing key in <Sortable>):

import React from 'react';
import Sortable from 'react-anything-sortable';
import { sortable } from 'react-anything-sortable';
import Link from 'valuelink'
import { Input, TextArea, Select, Radio, Checkbox } from 'valuelink/tags'
import shortid from 'shortid'

@sortable
class DemoHOCItem extends React.Component {

  constructor() {
      super();
      this.state = {
        info : ''
      };
    }

 componentWillMount() {
    console.log(this.props.sortData.value)
    this.setState( this.props.sortData.value );
  }


  render() {
    const linked = Link.all( this, 'sequence', 'info', 'other' ),
      infoLink   = this.props.sortData.at( 'info')

    const jointLink = Link.value( linked.info.value, x => {
      linked.info.set( x );
      infoLink.set( x);
    });


    return (
      <div {...this.props}>
        <span>{linked.sequence.value}</span>
        <Input valueLink={ jointLink }></Input>
      </div>
    );
  }
}

export default DemoHOCItem;

class Test extends React.Component {
  constructor() {
    super();
    this.state = {
      items: []
    };
  }

  componentDidMount() {
    console.log('Loading Route Sequences from server')
    fetch('http://uberfl.us/sortable.json')
    .then(
      response => {
        return response.json()
      }
    )
    .then(
      items => {
        this.setState(items)
        console.log(items)
      }
    )
  };

  handleSort(sortedArray) {
    console.log('Entering handleSort')
    var newItems = []
    var i=1
    console.log(sortedArray)
    sortedArray.map(function(item) {item.value.sequence=i, ++i, newItems.push(item.value)})
    console.log(newItems)
    this.setState({
      items: newItems
    });
  }

  render() {

    const itemsLink = Link.state( this, 'items' );


    function renderWithSortable(itemLink, index) {
      return (
        <DemoHOCItem className="vertical" sortData={ itemLink } key={ ['item',index].join('_') }>
          {console.log('Rendering Items')}
          {itemLink.sequence}
        </DemoHOCItem>
      );
    }

     return (
      <div className="demo-container">
         <Sortable className="vertical-container" onSort={::this.handleSort} key={shortid.generate()} dynamic>
          {itemsLink.map(renderWithSortable, this)}
        </Sortable>
      </div>
    );
  }
};

export default Test;

It is very fickle. Without the "dynamic"-property and a dynamic key in <Sortable> the items are not rendered. With the dynamic key the focus-issue appears.

But I got it working, following your advice, by using an incrementing key:

class Test extends React.Component {
  constructor() {
    super();
    this.state = {
      items: [],
      _sortableKey: 0
    };
  }

[..]
  handleSort(sortedArray) {
    console.log('Entering handleSort')
    this.state._sortableKey++;
    var newItems = []
    var i=1
    console.log(sortedArray)
    sortedArray.map(function(item) {item.value.sequence=i, ++i, newItems.push(item.value)})
    console.log(newItems)
    this.setState({
      items: newItems
    });
  }

[..]


render() {

    const itemsLink = Link.state( this, 'items' );

       return (
      <div className="demo-container">
         <Sortable className="vertical-container" onSort={::this.handleSort} key={ this.state._sortableKey } dynamic>
          {itemsLink.map(renderWithSortable, this)}
        </Sortable>
      </div>
    );
  }
};

Wohoo!!! Great stuff, thanks for your kind help!

from nestedlink.

gaperton avatar gaperton commented on July 29, 2024

This Sortable component is very tricky. I can't quickly understand how it works.

What about general sorting, React needs to know that element is moved. So, every element must have persistent index generated once and used as key in react list.

like this:

const list = [{ name: 'a', _id : 0}, { name: 'b', _id: 'whatever' }, ... ];

In your code, I think it should be enough to do it when you fetch elements from the server.
Then, no matter which permutation made on the list, React knows where every particular element is located, and should be able to preserve state.

So, you're supposed to generate list like this:

list.map( element => <div key={ element._id} > ... </div>

Id just must be unique value on this DOM level. If you already have something unique in the element (like image url) you can just use it as key.

It should work in the same way with link.map as well as with regular array.map. But again, this Sortable thingy does some dark magic in rendering, so I'm not completely sure if what I'm talking about is the case.

from nestedlink.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.