React / Preact .map一个图标,单击该图标可运行功能

时间:2018-12-01 21:09:43

标签: javascript reactjs preact

所以我在一个学校项目上得到了模糊的指导:

  

.map一个图标,单击该图标可运行一个功能,该功能将   .map作为参数,然后获取图像和音频

我没有任何可使用的基本代码。我只是不确定从哪里开始。使用.map

将对您有所帮助

2 个答案:

答案 0 :(得分:2)

这真的很模糊。您确定您的教授没有其他指示吗?您的教授是否希望将此作为网页上的元素或在桌面上运行的独立图标/ app / exe?

所以map是Array类的一个方法。它根据对初始数组的每个元素执行功能(回调)的结果创建一个新数组。 (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map

//example
const arrayOfNumbers = [1, 2, 3, 4]
// returns array of each element multiplied by 2
arrayOfNumbers.map(num => num*2)
// = [2, 4, 6, 8]

听起来您有某种映射(对象/哈希),该映射具有一个键并指向图像/音频源(URL)。似乎您需要单击某些图像/图标,从而触发事件处理程序,该事件处理程序的回调将是从该对象中获取键,并使用map将该对象中的键获取到您的文件源。然后您可以在DOM上显示它或其他内容?

但这听起来确实像您应该已收到其他信息来解决此问题。

答案 1 :(得分:1)

这是一个可以挖掘的实际示例。

  1. 我们首先创建一个记录库。该库只是我们要访问的一系列项目(以对象的形式)。数组中的每个对象都有一个ID(用于访问记录和存储活动记录ID),标题,图像url和声音文件url。

  2. 我们创建一个父组件,该组件包含用于设置活动记录ID的简单逻辑。我们实际上并没有在父组件的render方法中使用此函数,而是将其传递给<Record/>组件以使用。

  3. 我们在方法中渲染库,但是我们只是在映射<Record/>组件之前将库ID映射到新数组中,因为您的分配标准是通过映射ID返回图像和声音。

  4. 我们创建一个简单的组件来呈现记录,并使用从父组件传递下来的set属性设置活动记录ID。由于我们需要首先查找记录,因此我们使用find来过滤Library数组,以便我们有一个可用于显示标题的对象。

创建了handle click方法来运行set prop函数,因为我们不想只在render方法中执行onClick={() => this.props.set(this.props.id)},因为每次重新渲染组件时,它都会创建一个新函数。 (这是一种优化)

  1. 最后但并非最不重要的是,<ActiveRecord/>表示组件与上述类似,但是它根据已传递的活动记录ID查找记录。该组件呈现图像和声音。

玩一玩!这段代码可以缩短,但是我们真的想在评估标准上映射ID,这会使<Record/>组件稍微复杂一点(无需将整个记录向下传递,而必须使用{{1} })

让我知道是否需要更多信息。

注意:我们不使用类转换属性。

.find
/**
 * Static const that keeps a list of records
 */
const Library = [
  {
    id: 1,
    title: 'Service Bell',
    sound: 'http://soundbible.com/grab.php?id=2218&type=mp3',
    image: 'https://i.ebayimg.com/images/i/401039903298-0-1/s-l1000.jpg',
  },
  {
    id: 2,
    title: 'Dog',
    sound: 'http://soundbible.com/grab.php?id=2215&type=mp3',
    image: 'https://lovinlife.com/wp-content/uploads/2018/09/Dog.jpg',
  }
]

class App extends React.Component {
  constructor(props) {
    super(props);

    /**
     * State for storing selected record id
     */
    this.state = {
      activeRecordId: null,
    };

    this.setActiveRecord = this.setActiveRecord.bind(this);
  };

  /**
   * Sets active record
   * @param id {string}
   */
  setActiveRecord(id) {
    this.setState({
      activeRecordId: id,
    });
  };

  /**
   * Render
   */
  render() {
    return (
      <div className="App">
        <h5>Library</h5>
        {Library.map(record => record.id).map(recordId => <Record recordId={recordId} set={this.setActiveRecord} />)}
        {this.state.activeRecordId && <ActiveRecord activeRecordId={this.state.activeRecordId}/>}
      </div>
    )
  }
}

/**
 * Displays a record
 */
class Record extends React.Component {
  constructor(props) {
    super(props);

    // binds handle click so that you can access
    // props within the function
    this.handleClick = this.handleClick.bind(this);
  };

  /**
   * Call parent prop that sets the active record id back
   * in the parent container
   */
  handleClick() {
    this.props.set(this.props.recordId);
  };

  /**
   * Render record based on props
   */
  render() {
    const record = Library.find(record => record.id === this.props.recordId);
    return (
      <div>
        {record.title}
        <button onClick={this.handleClick}>View</button>
      </div>
    );
  }
}

/**
 * Displays an active record
 */
function ActiveRecord({ activeRecordId }) {
  const activeRecord = Library.find(record => record.id === activeRecordId);
  return (
    <div>
      <h3>Active Record</h3>
      <img width="100" src={activeRecord.image} />
      <audio controls>
        <source src={activeRecord.sound} type="audio/mp3" />
      </audio>
    </div>
  )
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);