简体   繁体   中英

ReactJS Modifying this.props data with a function and storing it into a class variable (like RoR setter)

I have an array of collection hashes in my react component stored with this format inside of this.props.collections:

[{id: 1, title: 'sunglasses', other_data: 'yougetthepoint'},{hash2}..etc}]

I'd like to use the below function to convert this to a single hash in this format

{ 'sunglasses': 1, 'necklaces': 2, etc}. 

How do I store this into my react component so I can lookup the id for each title? I'm thinking this would be similar to a setter in ruby on rails.

function CollectionHash(){
  var obj = this.props.collections.reduce(function ( total, current ) {
    total[ current.title ] = current.id;
    return total;
  }, {});
  return obj;
}

Full React Component

class ProductIndexPage extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      term: '',
      collection_id: null,
      products: this.props.products,
    };
    this.handleTermChange = this.handleTermChange.bind(this);
    this.handleCollectionChange = this.handleCollectionChange.bind(this);
  }

  handleTermChange(event) {
    this.setState({term: event}, () => {
      this.searchProducts()
    });
  }
  handleCollectionChange(event) {
    console.log('Handle Collection')
    console.log(this.collection_hash)
    console.log(event)
    this.setState({collection_id: event}, () => {
      this.searchProducts()
    });
  }
  render() {
    function CreateItem(product) {
      return { 
        url: '/products/' + product.id, 
        attributeOne: product.title,
        attributeTwo: product.variants[0].variant_price,
        attributeThree: '5 prices from $8.99 to $13.99',
        media: <Thumbnail
                  source={product.main_image_src}
                  alt={product.title}
                  size="small"
                />
      }
    }
    function CollectionTitles(collection) {
      return collection.title
    }
    function CollectionHash(){
      var obj = this.props.collections.reduce(function ( total, current ) {
        total[ current.title ] = current.id;
        return total;
      }, {});
      return obj;
    }
    return (
      <Layout>
        <Layout.Section>
          <Card title="Online store dashboard" actions={[{content: 'Edit'}]} sectioned>
            <Card.Section>
              <Stack>
                <TextField 
                  value={this.state.term}
                  label="Keyword Search"
                  placeholder="Enter Term"
                  onChange={this.handleTermChange}
                />
                <Select
                  value= {this.state.collection_id}
                  label="Collection"
                  options={ this.props.collections.map(CollectionTitles) }
                  placeholder="Select"
                  onChange={this.handleCollectionChange}
                  //onChange={this.valueUpdater('collection')}
                  //onChange={this.searchProducts('collection')}
                />
              </Stack>
            </Card.Section>
            <Card.Section>
                <ResourceList
                  items={
                      this.state.products.map(CreateItem)
                  }
                  renderItem={(item, index) => {
                    return <ResourceList.Item key={index} {...item} className='Polaris-Card' />;
                  }}
                />
            </Card.Section>
          </Card>
        </Layout.Section>
      </Layout>
    ); 
  }
searchProducts() {
  console.log('/products/' + "?term=" + this.state.term + "&collection=" + this.state.collection_id)
  $.ajax( {
    url: '/products/' + "?term=" + this.state.term + "&collection=" + this.state.collection_id,
    dataType: 'json',
    success: function(data) {
    this.setState({ products: data });
    }.bind(this),
    error: function(data) {
    }.bind(this)
   });
}

did you mean how to flatten your data in javascript ? if so you could simply do this

let flatten = {};
(product).forEach((x)=>{ 
   flatten[x.title] = x.id;
});

to make it accessible throughout your component, you could expose the local variable "flaten" into this.state or likewise

Best Regards,

John Jerrico

Turns out I had to store it in the constructor as a this.variable_name and not in a var name, and I can't just put the function outside of the constructor and call it and store it into a var variable = CollectionHash(). See solution below:

  class ProductIndexPage extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      term: '',
      collection_id: null,
      products: this.props.products,
    };
    this.handleTermChange = this.handleTermChange.bind(this);
    this.handleCollectionChange = this.handleCollectionChange.bind(this);
    this.col_hash = this.props.collections.reduce(function ( total, current ) {
        total[ current.title ] = current.id;
        return total;
      }, {});
  }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM