如何为选择字段赋予名称/值属性?

时间:2018-02-16 13:40:44

标签: javascript reactjs state dropdown semantic-ui

我有这两个功能:

  handleHomeInput = (e) => {
    let stateCopy = { ...this.state };
    stateCopy.home.name = e.target.innerText;
    this.setState(stateCopy);
  };

  handleAwayInput = (e) => {
    let stateCopy = { ...this.state };
    stateCopy.away.name = e.target.innerText;
    this.setState(stateCopy);
  };

显然非常相似,可以重构为1种方法。

这些方法都采用下拉列表的innerText。如果它们是正常输入,我可以从e.target.value获取名称或值属性,然后可以重构第3行。但这不可能,因为下拉列表似乎没有那个值参数。

顺便说一下,我正在使用语义ui。我有什么想法可以重构这些吗?

我的州看起来像这样:

state = {
    home: {
      name: '',
      goals: 0
    },
    away: {
      name: '',
      goals: 0
    },

2 个答案:

答案 0 :(得分:1)

您可以为输入命名:

handleInput = (e) => {
   const { name, innerText } = e.target
   const prevState = this.state[name]
   this.setState({ [name]: {...prevState, name: innerText } })
}

然后:

handleInput = (name) => (e) => {
   const { innerText } = e.target
   const prevState = this.state[name]
   this.setState({ [name]: {...prevState, name: innerText } })
}

或者,(以回答下面的评论)添加自定义字段名称:

<input onChange={this.handleInput('home')} ... />
<input onChange={this.handleInput('away')} ... />

然后您可以将其用作:

handleInput = (name) => (value) => {
   const prevState = this.state[name]
   this.setState({ [name]: {...prevState, name: value } })
}

或者,如果你想使它更通用:

<input onChange={(e) => this.handleInput('home')(e.target.innerText)} ... />
<input onChange={(e) => this.handleInput('away')(e.target.innerText)} ... />

然后将其用作:

// inputs
var input = "1,2,3,8,11,12";

// parse them as ints (ensure they are in ascending order)
var inputParsed = input.Split(',').Select(o => Convert.ToInt32(o)).OrderBy(o=> o).ToList();

// will contain results
var results = new List<List<int>>();

// will contain the current group building
var currentGroup = new List<int>();

// while we have number to parse we add them
while (inputParsed.Any())
{
    // get the current number
    var currentNumber = inputParsed[0];

    // if the current group is empty OR if the last number in is 1 less we can group it
    if (!currentGroup.Any() || currentGroup.Last() == currentNumber - 1)
    {
        // add current number to the group
        currentGroup.Add(currentNumber);                  
    }
    else
    {
        // current number doesn't match with the group so close the
        // group as it's finished and create a new one for this number

        // add the group to the list 
        results.Add(currentGroup);

        // create a new group
        currentGroup = new List<int>();

        // add current number to the group
        currentGroup.Add(currentNumber);
    }

    // remove the input we just checked
    inputParsed.RemoveAt(0);

    // check if there is any input left, if not the current group has to be added tp the results
    if (!inputParsed.Any())
    {
        // add the group to the list 
        results.Add(currentGroup);
    }
}

// parse single number as "1" and multiple number as "1-3"
var parseGroups = new Func<List<int>, string>((group) =>
{
    if (group.Count() == 1)
    {
        return group[0].ToString();
    }
    else
    {
        return group[0].ToString() + "-" + group.Last().ToString();
    }
});

// parse results
var parsedResults = string.Join(",", results.Select(parseGroups));

答案 1 :(得分:0)

在反应语义ui - https://react.semantic-ui.com/modules/dropdown#dropdown-example-search-selection-two中 - 它提供onChange事件

选项将以该格式传递:

const values = [{ 
 key: 'AL', 
 value: 'AL', 
 text: 'Alabama' 
}, ...]

<Dropdown 
  placeholder='State' 
  options={values} 
  onChange={(event, data) => console.log(event, data)} />

因此您应该将状态对象转换为匹配,然后您将获得所需的内容。 onChange将传递如下所示的数据对象:

{
  "placeholder": "State",
  "search": true,
  "selection": true,
  "options": [
    {
      "key": "AL",
      "value": "AL",
      "text": "Alabama"
    },
    ...
  ],
  "additionLabel": "Add ",
  "additionPosition": "top",
  "closeOnBlur": true,
  "deburr": false,
  "icon": "dropdown",
  "minCharacters": 1,
  "noResultsMessage": "No results found.",
  "openOnFocus": true,
  "searchInput": "text",
  "selectOnBlur": true,
  "selectOnNavigation": true,
  "value": "AL"
}

所以data.value是被选中的,也是 - 你给了所有选项的列表,所以你可以链接它。

  

docs声明他们将传递数据对象中的任何相关道具

所以,如果你有:

<Drodown name="one" onChange={(e, {name, value}) => console.log(`${name} changed to ${value}`) />
<Drodown name="two" onChange={(e, {name, value}) => console.log(`${name} changed to ${value}`) />

您现在可以轻松拥有一个只需根据需要更改状态的处理程序,例如。

handleChange(event, {name, value}){
  this.setState({[name]: { name: value }})
}