The first response that came to mind, after reading the question, was
BlockRandom[
With[{rand = RandomReal[]},
Which[
rand <= 0.2, reaction[[1]],
0.2 < rand <= 0.5, reaction[[2]],
0.5 < rand <= 1, reaction[[3]]]], RandomSeeding -> 123456798]
where, obviously, reaction = {0.2, 0.5, 1}. By replacing reaction[[i]] with i it is easy to obtain the index of the reaction (not the time it takes).
I think that, this is as literal an implementation as it gets.
A couple of other approaches are
BlockRandom[
With[{rand = RandomReal[]},
Extract[
reaction,
First[Position[Thread[rand <= reaction], True]]]
], RandomSeeding -> 123456798]
and
BlockRandom[
With[{rand = RandomReal[]},
Last[Flatten[Reap[
Scan[
If[rand <= #, Sow[#]; Return[]] &, reaction]]]]
], RandomSeeding -> 123456798]
In the former of the last two approaches, the index of the reaction instead of it's time can be obtained by replacing Extract[<>] with First[Flatten[Position[Thread[rand <= reaction], True]]].
The later code segment cannot be readily adjusted to obtain the index of the reaction instead of the time (at least not without doing something like First@Position[reaction, x] where x stands for the output of the last approach)
With[{q = RandomReal[]}, First@Flatten@Position[reaction, SelectFirst[reaction, q < # &]]]` – Coolwater Dec 27 '17 at 18:36MapIndexorOrdering– OkkesDulgerci Dec 27 '17 at 18:41wd=WeightedData[Range[3],Differences[{0, ##&@@reaction}]]; First@RandomSample[wd,1]? – kglr Dec 27 '17 at 18:56First@FirstPosition[reaction,_?(#>RandomReal[]&)]? – kglr Dec 27 '17 at 19:03